Count of non Null values in a Row - sql

Is there a better way of doing this?
select count(First)+count(id)+count(Last)+count(Telephone)
from client
where id ="1";

Not sure if this is better, but the intent may be clearer to someone reading it later:
select
(case when First is null then 1 else 0 end) +
(case when id is null then 1 else 0 end) +
(case when Last is null then 1 else 0 end) +
(case when Telephone is null then 1 else 0 end)
from client
where id ="1";

Related

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

How to use having condition in SQL query

SELECT
userid,
CASE
WHEN (COUNT(CASE
WHEN onlinesportsgamewagers != 0
THEN 1
ELSE null
END)
+ COUNT(CASE
WHEN depositmade_amt != 0
THEN 1
ELSE null
END)) >= 10
THEN "VIP"
ELSE "NON-VIP"
END as VIPcheck
FROM
player_activity
WHERE
userid = 2023410
GROUP BY
year(txndate), month(txndate)
This query determines the user's VIP status for each month.
Ultimately, I want to have a query that determines if the user achieved VIP status for at least 3 months (including the current month). For the time being, it's only user 2023410, but eventually I want to run this for the whole database.
Therefore my ultimate output would be:
User - VIPcheck (3 different months w/ active status)
(one row per userID)
HAVING COUNT(CASE WHEN (COUNT(CASE WHEN onlinesportsgamewagers != 0
THEN 1
ELSE null
END)
+ COUNT(CASE WHEN depositmade_amt != 0
THEN 1
ELSE null
END)) >= 10
THEN 1
ELSE 0
END)
Tried the above having statement, but it didn't work. Any suggestions?
If I understand correctly, this gets the VIP status for one user by month:
SELECT userid, year(txndate), month(txndate),
(CASE WHEN SUM(CASE WHEN onlinesportsgamewagers <> 0 THEN 1 ELSE 0 END) +
SUM(CASE WHEN depositmade_amt <> 0 THEN 1 ELSE 0 END) >= 10
THEN 'VIP'
ELSE 'NON-VIP'
END) as VIPcheck
FROM player_activity
GROUP BY userid, year(txndate), month(txndate);
Another aggregation will get what you want:
SELECT userid,
(CASE WHEN SUM(VIPcheck = 'VIP') >= 3 THEN 'SUPER-VIP'
WHEN SUM(VIPcheck = 'VIP') >= 1 THEN 'VIP'
ELSE 'HOI POLLOI'
END) as status
FROM (SELECT userid, year(txndate), month(txndate),
(CASE WHEN SUM(CASE WHEN onlinesportsgamewagers <> 0 THEN 1 ELSE 0 END) +
SUM(CASE WHEN depositmade_amt <> 0 THEN 1 ELSE 0 END) >= 10
THEN 'VIP'
ELSE 'NON-VIP'
END) as VIPcheck
FROM player_activity
GROUP BY userid, year(txndate), month(txndate)
) uym
GROUP BY userid;

how do I correctly use case when statement

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

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