This is my db schema:
http://sqlfiddle.com/#!3/bbaea/3
The only important columns are CreationTime (as a timestamp) and Result.
Result can currently be 0, 1, 2 or 3
What my result should look like:
Year, Month, Day | Entries with Result 0 | With 1 | With 2 | ..
I'm new to SQL Server itself and I have no idea how to solve this problem. I tried some subselects (like in my fiddle) but they are not working as expected. I guess this is because I have to join the subselects, but how? Also I want to know the best way of how to do this..
Some help?
You don't need to union several queries. You can use a case statement:
SELECT
DAY(CreationTime) AS d, MONTH(CreationTime) AS m, YEAR(CreationTime) AS y
,count(CASE WHEN RESULT = 0 THEN 1 ELSE NULL END) AS R0
,count(CASE WHEN RESULT = 1 THEN 1 ELSE NULL END) AS R1
,count(CASE WHEN RESULT = 2 THEN 1 ELSE NULL END) AS R2
FROM History
GROUP BY DAY(CreationTime), MONTH(CreationTime), YEAR(CreationTime)
SELECT * FROM History;
Answer on SQL Fiddle.
You can try this
SELECT YEAR(CreationTime) AS y, MONTH(CreationTime) AS m, DAY(CreationTime) AS d,
COUNT(CASE WHEN Result = 0 THEN 1 END) AS WITH0,
COUNT(CASE WHEN Result = 1 THEN 1 END) AS WITH1,
COUNT(CASE WHEN Result = 2 THEN 1 END) AS WITH2
FROM History
GROUP BY YEAR(CreationTime), MONTH(CreationTime), DAY(CreationTime)
Related
Sorry could not think of more descriptive title. I have data that looks like:
MEMBERID
TICKETID
STATUS
A
123
Y
A
012
N
A
456
Y
B
XYZ
N
B
ABC
N
C
DEF
Y
C
789
Y
I want to separate the above into three tables:
(1) Members that ONLY have tickets with Status=Y
(2) Members that have mixed status tickets (so at least one ticket with status=Y and at least one ticket with status=N)
(3) Members that ONLY have tickets with Status=N
In Excel I would just do a pivot table that results in something like:
MEMBERID
"Y"
"N"
A
2
1
B
0
2
C
2
0
...then add a 4th column with a formula that allows me to separate member IDs by "Only Y", "Only N", and "Y/N". I'm new to SQL though, and can't seem to get "pivot" to run correctly, or maybe there's a "where" clause that could resolve this without using pivot? Help!
You could pivot but it's probably simpler to just do the aggregation yourself:
select memberid,
count(case when status = 'Y' then ticketid end) as y,
count(case when status = 'N' then ticketid end) as n
from your_table
group by memberid
order by memberid;
To get the fourth column you can either repeat the counts within another case expression:
select memberid,
count(case when status = 'Y' then ticketid end) as y,
count(case when status = 'N' then ticketid end) as n,
case
when count(case when status = 'Y' then ticketid end) > 0
and count(case when status = 'N' then ticketid end) > 0
then 'Y/N'
when count(case when status = 'Y' then ticketid end) > 0
then 'Only Y'
when count(case when status = 'N' then ticketid end) > 0
then 'Only N'
end as yn
from your_table
group by memberid
order by memberid;
Or put the initial query into a CTE or inline view which is clearer and has less repetition, so easier to maintain:
select memberid, y, n,
case
when y > 0 and n > 0 then 'Y/N'
when y > 0 then 'Only Y'
when n > 0 then 'Only N'
end as yn
from (
select memberid,
count(case when status = 'Y' then ticketid end) as y,
count(case when status = 'N' then ticketid end) as n
from your_table
group by memberid
)
order by memberid;
Either way you end up with:
MEMBERID Y N YN
-------- - - ------
A 2 1 Y/N
B 0 2 Only N
C 2 0 Only Y
SQL Fiddle
My SQL Server problem is as follows: let's say we have clients and we wish to rate them based on 4 categories (Score_1...Score_4) on a scale of 0 to 2. I have a table presented below:
What I want my code to do is count the number of 0, 1, and 2 values each of my clients recieved. The result table I would like to get would like this:
So client_1 got two 0 scores, one 1 score and one 2 score, client_2 got one 0 score, one 1 score and two 2 scores. Any suggestions? Thanks in advance!
You can unpivot, then do conditional aggregation:
select t.id,
sum(case when x.score = 0 then 1 else 0 end) cnt_0,
sum(case when x.score = 1 then 1 else 0 end) cnt_1,
sum(case when x.score = 2 then 1 else 0 end) cnt_2
from mytable t
cross apply (values (score_1), (score_2), (score_3), (score_4)) x(score)
group by t.id
Here is my data
COUNTYID POLLUTANT TYPE EMISSION
1 A 1
1 A 2
1 B 1
1 B 2
2 A 1
2 A 2
2 B 1
2 B 2
3 A 1
3 A 2
3 B 1
3 B 2
if I do
SELECT sum(EMISSION) from table where POLLUTANT = 'A' group by COUNTYID;
I would get pollution from Polutant 'A'. how can I write a query to get following data:
column 1 with sum of A, column 2 with sum of B, column 3 with sum of A and B?
Thank you
You can use case for filter the value you need
select COUNTYID, sum(case when POLLUTANT='A'then EMISSION else 0 END) tot_a
, sum(case when POLLUTANT='B'then EMISSION else 0 END) tot_b
, sum(EMISSION) tot_a_b
from my_table
group by COUNTYID
You can use conditional aggregation. This moves the filtering conditions from the where clause to the sum()s:
select countyid,
sum(case when emission = 'A' then emission else 0 end) as A,
sum(case when emission = 'B' then emission else 0 end) as B,
sum(emission) as total
from t
group by countyid;
I would like to give some idea. We can use pivot table for answer your question
SELECT * from dbo.[Table_1]
PIVOT
(Sum([type_emmssion]) for [polutant] in ([A], [B]) ) as PivotTable
group by [CountryId] ;
you have to use case statemet:
SELECT
SUM( CASE WHEN POLLUTANT = 'A' THEN EMISSION ELSE 0 END) AS A_EMISSION
SUM( CASE WHEN POLLUTANT = 'B' THEN EMISSION ELSE 0 END) AS B_EMISSION
SUM(EMISSION) AS total_emission
FROM table
GROUP BY COUNTYID;
I'm looking to run a count SQL query on multiple columns at once. 83 of them. For each, I'd simply like to figure out how many instances there are in which the value = 1.
ex.
select count(*) from [filename.filename]
where [Column001] = 1
select count(*) from [filename.filename]
where [Column002] = 1
All data in each column is marked with wither a 0 or a 1.
Instead of writing 83 small queries, is there a way for me to write it all in one query and have them all display as a table with the results?
This seems to be what you want:
SELECT SUM(CASE WHEN Column_1 = 1 THEN 1 ELSE 0 END) N_1,
SUM(CASE WHEN Column_2 = 1 THEN 1 ELSE 0 END) N_2,
SUM(CASE WHEN Column_3 = 1 THEN 1 ELSE 0 END) N_3,
.....
SUM(CASE WHEN Column_83 = 1 THEN 1 ELSE 0 END) N_83
FROM YourTable;
I have a table like this:
user_id, gender, sent
1 M 100
1 F 120
2 M 20
2 F 30
I want a table like this from the above:
user_id, male_sent, female_sent, total_sent
1 100 120 220
2 20 30 50
I lack the (Postgres) SQL foo to figure this one out.
You can use an aggregate function with a CASE expression to get the result:
select user_id,
sum(case when gender = 'M' then sent else 0 end) male_sent,
sum(case when gender = 'F' then sent else 0 end) female_sent,
sum(sent) total_sent
from yourtable
group by user_id
See SQL Fiddle with Demo
What database are you using?
If you are using SQL Server, you could do something like this:
SELECT user_id,sum(case when gender = 'M' then sent else 0 end) as male_sent,
sum(case when gender = 'F' then sent else 0 end) as female_sent,
sum(sent) as total_sent
FROM your_table_name
GROUP BY user_id