how do I correctly use case when statement - sql

Hej,
I needed help with a case when statement in SQL Server.
Basically, I got three products and when the sum is equal to 2, then I want it to it be counted as 1 else 0. I wanted to know if the logic is write with this code or can it be improved?
case when sum(hase=1 OR hasd=1 OR hasf=1)=2 then 1 else 0 end as Xavc
What I was trying with this code is this: The customer might not have all three products however, if he has two products or the three the three , then it is equal to 2 and count is 1.

Something like this?
SELECT
CASE
WHEN hase + hasd + hasf = 2 THEN 1
ELSE 0
END AS Xavc

I think you are trying to do something like this...
CASE WHEN SUM(CASE WHEN hase=1 THEN 1 ELSE 0 END)
+ SUM(CASE WHEN hasd=1 THEN 1 ELSE 0 END)
+ SUM(CASE WHEN hasf=1 THEN 1 ELSE 0 END) = 2
THEN 1 ELSE 0 END AS Xavc
In this case try this ..
CASE WHEN SUM(CASE WHEN hase=1 THEN 1 ELSE 0 END) + SUM(CASE WHEN hasd=1 THEN 1 ELSE 0 END) = 2
OR SUM(CASE WHEN hasd=1 THEN 1 ELSE 0 END) + SUM(CASE WHEN hasf=1 THEN 1 ELSE 0 END) = 2
OR SUM(CASE WHEN hase=1 THEN 1 ELSE 0 END) + SUM(CASE WHEN hasf=1 THEN 1 ELSE 0 END) = 2
THEN 1 ELSE 0 END AS Xavc

Related

Hello! is that anyway to write similar query without using union?

is that anyway to write similar query without using union?
select sum(decode(p.sumsend,0,1,0)) recvcnt,
sum(decode(p.sumsend,0,1,0)*p.sumserv) recvsum
from some_table p
where p.polefilter = 5
union
select sum(decode(p.sumsend,0,1,0)) recvcnt,
sum(decode(p.sumsend,0,1,0)*p.sumserv) recvsum
from some_table p
where p.polefilter != 5
If you are OK with having all 4 columns on one row, then one option is conditional aggregation:
select
sum(case when polefilter = 5 and sumsend = 0 then 1 else 0 end) recvcnt1,
sum(case when polefilter = 5 and sumsend = 0 then 1 else 0 end * sumserv) recvsum1,
sum(case when polefilter <> 5 and sumsend = 0 then 1 else 0 end) recvcnt2,
sum(case when polefilter <> 5 and sumsend = 0 then 1 else 0 end * sumserv) recvsum2
from some_table p
where polefilter is not null
On the other hand, if you want two rows in the resultset, then you can use aggregation and a case expression to define the groups:
select
case when polefilter = 5 then 1 else 0 end as polefilter_is_5
sum(case when sumsend = 0 then 1 else 0 end) recvcnt,
sum(case when sumsend = 0 then 1 else 0 end * sumserv) recvsum1
from some_table p
where p.polefilter is not null
group by case when polefilter = 5 then 1 else 0 end
Note that I changed the decode() functions to case expressions; both do the same thing, but the latest is standard SQL (and is somehow more flexible).
A query like the one below should work. Please provide sample data and expected output when asking a question next time.
SELECT SUM (CASE WHEN p.sumsend = 0 THEN 1 ELSE 0 END) recvcnt,
SUM (CASE WHEN p.sumsend = 0 THEN 1 ELSE 0 END * p.sumserv) recvsum
FROM some_table p
GROUP BY CASE p.polefilter WHEN 5 THEN 1 ELSE 0 END;

I need to Count the Number of Columns that have value more than 0 in SQL

I want to create a calculated field at the end of the columns where it will count all the Columns having values greater than 0.
Below is a sample Data Set.
Account_number DAY_0 DAY_30 DAY_60 DAY_90 DAY_120
acc_001 99 10 0 0.2 0
You can use case expressions:
select t.*,
( (case when day_0 > 0 then 1 else 0 end) +
(case when day_30 > 0 then 1 else 0 end) +
(case when day_60 > 0 then 1 else 0 end) +
(case when day_90 > 0 then 1 else 0 end) +
(case when day_120 > 0 then 1 else 0 end)
) as num_gt_zero
from t;
That said, you probably constructed this from a group by query. You might be able to put this logic directly into that query. If that is the case, ask a new question, with sample data, desired results, and an appropriate database tag.

Create and classify a row based on column values

I am attempting to assign a classification to a row of data based on whether certain values exist. Utilizing the sample code below I have gotten to a place where I've gotten stuck.
proc sql;
create table test
(id char(4),
task char(4),
id2 char(4),
status char(10),
seconds num);
insert into test
values('1','A','1','COMP',15)
values('1','B','2','WORK',20)
values('1','C','3','COMP',50)
values('1','D','3','COMP',null)
values('2','A','1','COMP',15)
values('2','B','2','COMP',520)
values('2','C','2','COMP',NULL)
values('2','D','3','COMP',221)
values('2','E','3','COMP',null)
values('2','F','3','COMP',null);
proc sql;
create table test2 as
select
ID,
ID2,
STATUS,
SUM(SECONDS) AS SECONDS,
sum(case when task='A' THEN 1 ELSE 0 END) AS A,
sum(case when task='B' THEN 1 ELSE 0 END) AS B,
sum(case when task='C' THEN 1 ELSE 0 END) AS C,
sum(case when task='D' THEN 1 ELSE 0 END) AS D,
sum(case when task='E' THEN 1 ELSE 0 END) AS E,
sum(case when task='F' THEN 1 ELSE 0 END) AS F
from
test
GROUP BY
ID,
ID2,
STATUS
;
quit;
Ultimately I would like to classify each row that gets created in the second step 'test2' to have a column that looks to the values in each lettered column(A-F) and Label them as such. So when the Row has a 1 in Column A only, it would be labeled 'A' but when a row has a 1 in multiple columns like 'D', 'E' and 'F' I would like it to be labeled as D_E_F.
Best way to do this is in a DATA STEP:
data test3;
format classifier $32.;
set test2;
array vars[6] A B C D E F;
classifier = "";
do i=1 to 6;
if vars[i] then
classifier = catx("_",classifier,vname(vars[i]));
end;
drop i;
run;
I create a character variable CLASSIFIER with length 32.
I define an array that groups the columns A through F. This allows me to loop over those columns easily.
Initialize the CLASSIFIER variable.
Loop over the array. If the value =1, then add the name of the variable to the CLASSIFIER string.
CATX(delim,str1,str2) concatenates str1 and str2 with the delim in the middle. It also removes whitespace.
VNAME(array[i]) returns the variable name of the variable pointed to by array[i].
Finally remove the i loop variable, unless you really want it in your output.
I know it is ugly, but you can do it with CASE statements accumulating the wanted result in another field. You have the SQL Fiddle here.
Note that if it is possible that the concatenation is empty you will have to check this condition to avoid performing the substring.
select
ID,
ID2,
STATUS,
SUM(SECONDS) AS SECONDS,
sum(case when task='A' THEN 1 ELSE 0 END) AS A,
sum(case when task='B' THEN 1 ELSE 0 END) AS B,
sum(case when task='C' THEN 1 ELSE 0 END) AS C,
sum(case when task='D' THEN 1 ELSE 0 END) AS D,
sum(case when task='E' THEN 1 ELSE 0 END) AS E,
sum(case when task='F' THEN 1 ELSE 0 END) AS F,
substring(
case when sum(case when task='A' THEN 1 ELSE 0 END) = 1 then '_A' else '' end
+ case when sum(case when task='B' THEN 1 ELSE 0 END) = 1 then '_B' else '' end
+ case when sum(case when task='C' THEN 1 ELSE 0 END) = 1 then '_C' else '' end
+ case when sum(case when task='D' THEN 1 ELSE 0 END) = 1 then '_D' else '' end
+ case when sum(case when task='E' THEN 1 ELSE 0 END) = 1 then '_E' else '' end
+ case when sum(case when task='F' THEN 1 ELSE 0 END) = 1 then '_F' else '' end,
2, len(case when sum(case when task='A' THEN 1 ELSE 0 END) = 1 then '_A' else '' end
+ case when sum(case when task='B' THEN 1 ELSE 0 END) = 1 then '_B' else '' end
+ case when sum(case when task='C' THEN 1 ELSE 0 END) = 1 then '_C' else '' end
+ case when sum(case when task='D' THEN 1 ELSE 0 END) = 1 then '_D' else '' end
+ case when sum(case when task='E' THEN 1 ELSE 0 END) = 1 then '_E' else '' end
+ case when sum(case when task='F' THEN 1 ELSE 0 END) = 1 then '_F' else '' end) - 1) as wantedOutput
from
test
GROUP BY
ID,
ID2,
STATUS

Finding the values from same table that have value 1 and 2 but not 3

Hi I have the below table where I want to find the object_ida that I have format_id 1,3,11 and 12 but not 10. Could you please help?
You can use group by and having:
select object_id
from t
group by object_id
having sum(case when format_id = 1 then 1 else 0 end) > 0 and
sum(case when format_id = 3 then 1 else 0 end) > 0 and
sum(case when format_id = 11 then 1 else 0 end) > 0 and
sum(case when format_id = 12 then 1 else 0 end) > 0 and
sum(case when format_id = 10 then 1 else 0 end) = 0;
Each condition tests for one of the format_ids. The > 0 means that at least one is assigned to an object_id. The = 0 means that none are assigned.

How to add cases across columns that meet a condition, within rows?

I have data on household ownership of appliances, with one appliance per column, and data in the format of Y or N. I want to generate a new column with the sum of appliances owned per household. When I run the following script (SQLIte), I get an error message about syntax error near ")". Please help - I've tried all sorts of syntax.
SELECT Household,
SUM((CASE WHEN Stove="Y" THEN 1 ELSE 0) +
(CASE WHEN Fridge="Y" THEN 1 ELSE 0) +
(CASE WHEN TV="Y" THEN 1 ELSE 0) +
(CASE WHEN Video="Y" THEN 1 ELSE 0) +
(CASE WHEN SatDish="Y" THEN 1 ELSE 0) +
(CASE WHEN Radio="Y" THEN 1 ELSE 0) +
(CASE WHEN FixPhone="Y" THEN 1 ELSE 0) END)
AS Appliances
FROM Assets
You need End with every case statement:
Try this:
SELECT Household,
SUM((CASE WHEN Stove="Y" THEN 1 ELSE 0 End) +
(CASE WHEN Fridge="Y" THEN 1 ELSE 0 End) +
(CASE WHEN TV="Y" THEN 1 ELSE 0 End) +
(CASE WHEN Video="Y" THEN 1 ELSE 0 End) +
(CASE WHEN SatDish="Y" THEN 1 ELSE 0 End) +
(CASE WHEN Radio="Y" THEN 1 ELSE 0 End) +
(CASE WHEN FixPhone="Y" THEN 1 ELSE 0 End))
AS Appliances
FROM Assets
Group By Household