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 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.
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
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.
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