GROUP BY a column in the same table to two alias columns - sql

I have this table:
table
And I want to know if there is some SQL query to return something like this:
result
I tried this but didn't work:
SELECT Object,
SUM(CASE WHEN Key = 'A' THEN Qty END) As Key A,
SUM(CASE WHEN Key = 'B' THEN Qty END) As Key B
FROM tab
And even added the GROUP BY clause but the error is at the CASE clause

I would expect something like this:
SELECT Object,
SUM(CASE WHEN Key = 'A' THEN Qty END) As KeyA,
SUM(CASE WHEN Key = 'B' THEN Qty END) As KeyB
FROM table -- table won't work as a table name
GROUP BY object;
I added the GROUP BY and fixed the column aliases.

add group by in your query as you execute the aggregation
SELECT Object,
SUM(CASE WHEN Key = 'A' THEN Qty END) As Key_A,
SUM(CASE WHEN Key = 'B' THEN Qty END) As Key_B
FROM table group by Object
you have used space of column alias name i changed it

Related

SQL query - group by string prefix

I'm struggling with a grouping query.
I have simple table named CarParts where some car elements stored in it.
Some of those elements are available (with Type prefix "05") and some are blocked (Type prefix "01").
I want to write select query that would group my table CarParts by SerialNr and Type as shown below on the right side.
Do you want conditional aggregation?
select serialnr, name,
sum(case when type like '%-05' then amount else 0 end) as [05-available],
sum(case when type like '%-01' then amount else 0 end) as [01-blocked]
from carparts
group by serialnr, name;
You can use PIVOT to get your desired result as below-
SELECT SerialNr,
ISNULL([05-Available],0) [05-Available],
ISNULL([01-Available],0) [01-Available],
Name
FROM
(
SELECT SerialNr,Amount,Name,RIGHT( Type,2) +'-Available' AS P_Column
FROM CarParts
) AS P
PIVOT
(
SUM(Amount)
FOR P_Column IN ([01-Available],[05-Available])
) AS PVT
you can use case when
select SerialNr,Name,
sum(case when right([Type],2)='01' then amount else 0 end) as blocked_01
sum(case when right([Type],2)='05' then amount else 0 end) as availabe_05
from tbale_name group by SerialNr,Name
select SerialNr,
sum(case when Type like '%-05' then Amount else 0 end) as '05-available',
sum(case when Type like '%-01' then Amount else 0 end) as '01-blocked',
Name
from carparts
group by SerialNr, Name

sum distinct value while using distinct id

I am working on a data that looks like this:
from the table the gender (M,F) has the same globalid, however, I need to sum the distinct globalid's value column based on the gender (total from M and F).
I have tried this code but the query just returned the same data.
select distinct (globalid) globalid, fcname, featureidentifier,
gender, source, wardcode,sum (distinct value)
from public.kano_pp
source= 'Worldpop / ORNL Adjusted'
group by globalid, fcname, featureidentifier,gender, source, wardcode, value
order by globalid;
I think you want something more like this:
select globalid,
sum(case when gender = 'F' then value else 0 end) as female_value,
sum(case when gender = 'M' then value else 0 end) as male_value
from public.kano_pp
where source = 'Worldpop / ORNL Adjusted'
group by globalid
order by globalid;
The more recent versions of Postgres support the filter clause which is a bit more efficient than the sum(case . . ).

Use EXISTS in SQL for multiple select

I have a table STATUSES which contain columns NAME and ACTIVE_FLAG.The column value of NAME may have new, pending, cancel. I want to generate a new output for the count of each NAME with ACTIVE_FLAG=Y
By thinking to use EXISTS to select records for single NAME,
SELECT COUNT(*) AS PENDING
FROM STATUSES
WHERE EXISTS (select NAME from STATUSES where NAME='Pending' and ACTIVE_FLAG = 'Y')
Anyway if I can join other statuses count in a single SQL?
Seems like count and group by
SELECT
name
, count(*)
FROM statuses
WHERE active_flag = 'Y'
GROUP BY name
You can use something like this as i don't see any need to use EXISTS :
SELECT sum(case when name='Pending' then 1 else 0 end) AS PENDING,
sum(case when name='new' then 1 else 0 end) AS NEW,
sum(case when name='cancel' then 1 else 0 end) AS CANCEL
FROM STATUSES
WHERE ACTIVE_FLAG = 'Y'
SQL HERE

pivot table returns more than 1 row for the same ID

I have a sql code which I am using to do pivot. Code is as follows:
SELECT DISTINCT PersonID
,MAX(pivotColumn1)
,MAX(pivotColumn2) --originally these were in 2 separate rows)
FROM(SELECT srcID, PersonID, detailCode, detailValue) FROM src) AS SrcTbl
PIVOT(MAX(detailValue) FOR detailCode IN ([pivotColumn1],[pivotColumn2])) pvt
GROUP BY PersonID
In the source data the ID has 2 separate rows due to having its own ID which separates the values. I have now pivoted it and its still giving me 2 separate rows for the ID even though i grouped it and used aggregation on the pivot columns. Ay idea whats wrong with the code?
So I have all my possible detailCode listed in the IN clause. So I have null returned when the value is none but I want it all summarised in 1 row. See image below.
If those are all the options of detailCode , you can use conditional aggregation with CASE EXPRESSION instead of Pivot:
SELECT t.personID,
MAX(CASE WHEN t.detailCode = 'cas' then t.detailValue END) as cas,
MAX(CASE WHEN t.detailCode = 'buy' then t.detailValue END) as buy,
MAX(CASE WHEN t.detailCode = 'sel' then t.detailValue END) as sel,
MAX(CASE WHEN t.detailCode = 'pla' then t.detailValue END) as pla
FROM YourTable t
GROUP BY t.personID

Summarize multiple transactions that share a common value but also have unique row identifiers

I'm currently working with a data set that has a large number of unique groups, and within each group there could be one to many unique rows, to describe the type of transaction applicable to that group. There are a limited number of types of transactions, and each transaction has a(n):
Amount
Location
Date
The data set would look something like this:
What I would like it to do is combine all groups into a single line, and have three columns for each type of transaction. I am trying to get the end result to look like this:
The closest I have gotten is to try a number of joins, based on the claim number while looking for the unique key. Unfortunately my results end up looking like this:
Any suggestions on how to get each unique Group to have only one row in the results, with the three Types spread out, having three columns each?
You can do this all with conditional aggregation:
select grp,
sum(case when type = 'S' then amount else null end) as type_s_amt,
min(case when type = 'S' then location else null end) as type_s_loc,
min(case when type = 'S' then date else null end) as type_s_dt,
sum(case when type = 'O' then amount else null end) as type_o_amt,
min(case when type = 'O' then location else null end) as type_o_loc,
min(case when type = 'O' then date else null end) as type_o_dt,
sum(case when type = 'F' then amount else null end) as type_f_amt,
min(case when type = 'F' then location else null end) as type_f_loc,
min(case when type = 'F' then date else null end) as type_f_dt
from tbl
group by grp
Fiddle: http://sqlfiddle.com/#!3/f7fae/5/0