case statement same column - sql

have column that has values of total and hours inside it but I need to split the group into two columns
for example
select
case
when A.TYPE = 'H'
then A.Value
end as "Hours",
Case
when A.TYPE != 'H'
then A.VALUE
end as "Total"
from a
what this is returning is 2 columns but doubling it not a lining values.
Hours Total
2 null
null 20

Your table would appear to have two rows. If you want one row in the result set you need aggregation:
select max(case when A.TYPE = 'H' then A.Value end) as Hours,
max(case when A.TYPE <> 'H' then A.VALUE end) as Total
from a;

Related

How to select multiple columns and group by one column

I want to sum C.AMOUNT based on the number column. For example the number column in the same 4 numbers, then I want to sum the column C.AMOUNT based on the same number in the number column and display the summed column in the FINAL_AMOUNT column
SELECT A.NUMBER,
B.AGE,
C.PRODUCT_NAME,
SUM(C.AMOUNT) AS FINAL_AMOUNT,
(CASE
WHEN C.PRODUCT_NAME LIKE '%D%'
THEN 'Y'
ELSE 'N'
END) AS D,
(CASE
WHEN C.PRODUCT_NAME LIKE '%E%'
THEN 'Y'
ELSE 'N'
END) AS E,
(CASE
WHEN C.PRODUCT_NAME LIKE '%F%'
THEN 'Y'
ELSE 'N'
END) AS F,
(CASE
WHEN C.PRODUCT_NAME LIKE '%G%'
OR C.PRODUCT_NAME LIKE '%H%'
OR C.PRODUCT_NAME LIKE '%J%'
THEN 'Y'
ELSE 'N'
END) AS J
FROM [A].[DBO].[A]
LEFT JOIN [B].[DBO].[B] B ON A.NUMBER = B.NUMBER
LEFT JOIN [C].[DBO].[C] C ON A.NUMBER = C.NUMBER
WHERE B.REPORT_DATE = '20200728'
GROUP BY A.NUMBER;
That is the query I used but I find error like this:
Msg 8120, Level 16, State 1, Line 1 Column 'B.DBO.B' is invalid in
the select list because it is not contained in either an aggregate
function or the GROUP BY clause.
It looks like you want a window sum rather than aggregation.
That is, replace:
SUM(C.amount) as FINAL_AMOUNT
With:
SUM(C.amount) OVER(PARTITION BY A.NUMBER) as FINAL_AMOUNT
Accordingly, you need to remove the GROUP BY clause from the query.

total and group multiple column values in a single query

I am looking to get a summary of multiple states from the same column.
select c.brand
sum amount as total
from charges as c
where c.invoive_id is not null
and c.paid = true
group by c.brand
gets me the sum of all completed purchases grouped by brand.
I want to have a separate column in the same query, summed by brand for "c.paid = false"
so I will have:
Brand Total(true) Total(false)
b_one 25 12
b_two 38 16
You seems to have a simple conditional aggregation statement -
SELECT c.brand
,SUM(CASE WHEN c.paid = 'true' THEN amount END) as Total(true)
,SUM(CASE WHEN c.paid = 'false' THEN amount END) as Total(false)
from charges as c
where c.invoive_id is not null
group by c.brand
You don't say which database you are using so I'll assume PostgreSQL. You can usually use a CASE clause to do this. For example:
select
c.brand,
sum(case when c.paid then 1 else 0 end) as total_true,
sum(case when c.paid then 0 else 1 end) as total_false
from charges as c
where c.invoive_id is not null
group by c.brand
In databases that support boolean types, you can often do:
select c.brand,
sum(c.paid) as num_true,
sum(not c.paid) as num_falst
from charges as c
where c.invoive_id is not null
group by c.brand

How to convert a single column containing multiple rows into rows

I have a column , says name Student_name and its values lets say, A, B, C, D, E, F and so on..
Now i have to convert this column into row with each alias.
select A.counts from (
select count(b.ATTND_FLAG) as counts , b.ATTND_FLAG as ATTND_FLAG
from hr_emp_notifications a, v_emp_attendance b
where a.emp_id=b.emp_id
and a.emp_id=90327
and b.ATTND_FLAG is not null
group by b.ATTND_FLAG )A
my query showing one column which has multiple values in rows.
i have to convert these values into row.
I would use conditional aggregation:
select sum(case when ea.attnd_flag = 'A' then 1 else 0 end) as num_a,
sum(case when ea.attnd_flag = 'B' then 1 else 0 end) as num_b,
sum(case when ea.attnd_flag = 'C' then 1 else 0 end) as num_c,
sum(case when ea.attnd_flag = 'D' then 1 else 0 end) as num_d,
sum(case when ea.attnd_flag = 'E' then 1 else 0 end) as num_e,
sum(case when ea.attnd_flag = 'F' then 1 else 0 end) as num_f
from v_emp_attendance ea
where ea.emp_id = 90327;
If you want multiple employees, use group byea.emp_id`.
Notice that the join is not needed.
It seems you need a pivot clause here -
SELECT *
FROM (SELECT NAME, ATTND_FLAG
FROM v_emp_attendance)
PIVOT (COUNT(ATTND_FLAG)
FOR NAME IN ('A' AS A, 'B' AS B, 'C' AS C /* AND SO ON */)
)

Create Multiple Count Columns using Case When

I have to Case statements that count the same column just with a differnt criteria. The problem i am having is that the first case creates a null entry in the Test2 column but then counts it on my second case statement and leaves the Test 1 column null. I would like to have both counts side by side instead of created a duplicate row.
select m.no,
Case when itemtype = 'S' THEN count(ITEMKEY) end as Test1,
case when ItemType='C' THEN count(ITEMKEY) END as Test2
from test m
I'm pretty sure you want conditional aggregation. The case expression is an argument to the aggregation function:
select m.no,
sum(case when itemtype = 'S' then 1 else 0 end) as test1,
sum(case when itemtype = 'C' then 1 else 0 end) as test2
from test m
group by m.no;
This assumes that itemKey is never null, so the count() is just counting rows.
Following query can display records which having Itemtype 'S' or 'C' with count of itemkey. if itemkey is null it will display 0 else count of item key
select m.no,
Case when isnull( m.itemtype = 'S',0) THEN (select count(a.ITEMKEY) from test a where a.itemtype = 'S' ) else 0 end as Test1,
case when isnull( m.itemtype='C',0) THEN (select count(b.ITEMKEY) from test b where b.itemtype = 'C') else 0 END as Test2
from test m

SQL : Group by and check if all, some or none are set

Lets say I have the following table:
FKEY A B C D E F
'A' 1 0 1 0 1 0
'A' 0 1 1 1 0 0
Now i want to make a group by FKEY but I just want to know if the A-F columns has 1 in one, all or none of the grouped rows.. The resulton the above table would be:
FKEY A B C D E F
'A' S S A S S N
..where S is "some", A is "all" and N is "none".
What would be the best approach to make this query. I could so some nested queries, but isnt there a smarter way?
In my real life data, the 1's and 0's are actually DATETIME and NULL's
You can use case and aggregation:
select fkey,
(case when sum(a) = 0 then 'N'
when sum(a) = count(*) then 'A'
else 'S'
end) as a,
(case when sum(b) = 0 then 'N'
when sum(b) = count(*) then 'A'
else 'S'
end) as b,
. . .
from t
group by fkey;
The above assumes that the values are only 0 and 1. If that is the case, you can actually phrase this as:
(case when max(a) = 0 then 'N'
when min(a) = 1 then 'A'
else 'S'
end) as a,
You mentioned that your 0 and 1 are actually null or non null dates. Here's a modified version of Gordon's query that caters for that:
select fkey,
(case when count(datecol) = 0 then 'all dates are null'
when count(datecol) = count(*) then 'all dates are filled'
else 'some are null, some filled'
end) as a,
...
from t
group by fkey;
COUNT(null) is 0, COUNT('2001-01-01') is 1, COUNT(*) is the row count independent of any variable. Hence, if our count of the dates was 0, all must be null. If the count of the dates was equal to the count of the rows, then all must be filled with some value, otherwise it's a mix