Mimicking an excel pivot in SQL [duplicate] - mysql

This question already has answers here:
How can I return pivot table output in MySQL?
(10 answers)
Closed 5 years ago.
Been a long time since I've been in the DB world as I'm now primarily a front end developer.
I have a sql db table that looks like this :
Email | State | Status
___________________________________________________
bob#email.com Colorado 1
jim#email.com North Carolina 2
sarah#email.com Colorado 3
fred#email.com North Carolina 2
I need a query that makes a table that looks like this :
State | 1 | 2 | 3 | Total
_________________________________________________________________
Colorado 1 0 1 2
North Carolina 0 2 0 2
Any help is appreciated

select
State,
sum(case when Status=1 then 1 else 0 end) '1',
sum(case when Status=2 then 1 else 0 end) '2',
sum(case when Status=3 then 1 else 0 end) '3',
sum(case when Status>0 then 1 else 0 end) 'total'
from Your_Table
group by State

Related

MySQL with CASE WHEN with multiple values [duplicate]

This question already has answers here:
How do I use properly CASE..WHEN in MySQL
(6 answers)
Closed 4 years ago.
I'm trying to display the sum of my severity levels.
My Table
client dateadded problem level
abc 2019-02-02 12345a 1
abc 2019-02-02 12345b 1
abc 2019-02-02 12345c 2
abc 2019-02-02 12345d 5
abc 2019-02-09 12345e 3
abc 2019-02-09 12345f 3
abc 2019-02-09 12345g 4
abc 2019-02-09 12345h 10
abc 2019-02-09 12345j 8
abc 2019-02-16 12345x 7
abc 2019-02-16 12345s 9
abc 2019-02-16 12345w 4
abc 2019-02-16 12345bs 5
This is my code
select client, dateadded,
count(case when level= '1,2,3' then 1 end) as Moderate,
count(case when level= '4,5,6,7' then 1 end) as Severe,
count(case when level= '8,9,10' then 1 end) as Critical
from table1 where client = 'abc'
group by client, dateadded
I tried
count(case when level= '1' and '2' and '3' then 1 end) as Moderate,
My desired output
dateadded Moderate severe critical
2019-02-02 3 1 0
2019-02-09 2 1 2
2019-02-16 0 3 2
Thanks!
Nathalie
CASE WHEN level IN(1,2,3) THEN 1 END ... was the way to go.. thanks all!
Can you try with IN condition in case and group by dateadded
select client, dateadded,
count(case when level IN (1,2,3) then 1 end) as Moderate,
count(case when level IN (4,5,6,7) then 1 end) as Severe,
count(case when level IN (8,9,10) then 1 end) as Critical
from table1 where client = 'abc'
group by dateadded, client

Transpose the results of a MySQL query that outputs ranges

My source table (wplott_wpkl_winner) contains the field "lottery_number" that carries 1 to 6 digit numbers and the corresponding "draw_date".
lottery_number | draw_date
==================================
0024 | 2018-11-10
4456 | 2018-11-10
3895 | 2018-11-10
4557 | 2018-11-10
4225 | 2018-11-10
2896 | 2018-11-10
3354 | 2018-11-10
1895 | 2018-11-10
78466 | 2018-11-10
998556 | 2018-11-10
My current MYSQL query is as below (I am trying to group the data into ranges)
select
count(case when wplott_wpkl_winner.lottery_number between 0 and 999 then 1 end) `0-999`,
count(case when wplott_wpkl_winner.lottery_number between 1000 and 1999 then 1 end) `1000-1999`,
count(case when wplott_wpkl_winner.lottery_number between 2000 and 2999 then 1 end) `2000-2999`,
count(case when wplott_wpkl_winner.lottery_number between 3000 and 3999 then 1 end) `3000-3999`,
count(case when wplott_wpkl_winner.lottery_number between 4000 and 4999 then 1 end) `4000-4999`,
count(case when wplott_wpkl_winner.lottery_number between 5000 and 5999 then 1 end) `5000-5999`,
count(case when wplott_wpkl_winner.lottery_number between 6000 and 6999 then 1 end) `6000-6999`,
count(case when wplott_wpkl_winner.lottery_number between 7000 and 7999 then 1 end) `7000-7999`,
count(case when wplott_wpkl_winner.lottery_number between 8000 and 8999 then 1 end) `8000-8999`,
count(case when wplott_wpkl_winner.lottery_number between 9000 and 9999 then 1 end) `9000-9999`
from wplott_wpkl_winner
where CHAR_LENGTH(wplott_wpkl_winner.lottery_number) = 4 AND wplott_wpkl_winner.draw_date > '2013-06-30'
It provides the below output
0-999 | 1000-1999 | 2000-2999 | 3000-3999 | 4000- 4999 .... etc
=====================================================================
1 | 1 | 1 | 2 | 3
However, I would like to get the output in the below format.
Range | Count
=======================
0-999 | 1
1000-1999 | 1
2000-2999 | 1
3000-3999 | 2
4000-4999 | 3
.
.
.
Any help is highly appreciated. I did search in SO for a similar answer but none of the answers helped my particular case.
Thanks in advance!
One approach uses a series of unions:
SELECT
`range`,
count
FROM
(
SELECT 1 AS pos, '0-999' AS `range`, COUNT(*) AS count
FROM wplott_wpkl_winner
WHERE draw_date > '2013-06-30' AND lottery_number BETWEEN 0 AND 999
UNION ALL
SELECT 2, '1000-1999', COUNT(*)
FROM wplott_wpkl_winner
WHERE draw_date > '2013-06-30' AND lottery_number BETWEEN 1000 AND 1999
UNION ALL
... -- fill in remaining ranges here
) t
ORDER BY pos;
Note that I introduce a computed column pos so that we may maintain the desired ordering of the ranges in the final output. Also, I removed the check on the CHAR_LENGTH of the lottery_number, since the conditional sums already handle this logic.

Transpose a table

I am using Mysql and I want count distinct value and then make the distinct values as the column name.
I have a table Students like this
ID Names Age
1 Tim 12
2 James 14
3 White 13
4 John 13
5 Annie 11
6 Judy 13
I want to find how many people in each age. My expected result is:
11 12 13 14
1 1 3 1
I tried the query: "Select count(age), age from Students group by age;"
It gives out:
count(age) age
1 11
1 12
3 13
1 14
How can I take a "transpose" to the table?
If you are using MySQL you will need to know age in advance:
SELECT
SUM(CASE WHEN (age='11') THEN 1 ELSE 0 END) AS 11,
SUM(CASE WHEN (age='12') THEN 1 ELSE 0 END) AS 12,
SUM(CASE WHEN (age='13') THEN 1 ELSE 0 END) AS 13,
SUM(CASE WHEN (age='14') THEN 1 ELSE 0 END) AS 14
FROM
Students

Group by 2 field in mysql [duplicate]

This question already has answers here:
multiple query same table but in different columns mysql
(4 answers)
Closed 6 years ago.
how to group by data with 2 column but the result is in 1 row (like when we join it).
this is the table 'jembatan'
id nama tahun jumlah
-----------------------------
1 A 2011 12
2 B 2011 10
3 A 2011 23
4 B 2012 11
i want the result like this:
id totalA totalB tahun
---------------------------------
25 10 2011
0 11 2012
how to do like that?
You want conditional aggregation:
select sum(case when nama = 'A' then jumlah else 0 end) as TotalA,
sum(case when nama = 'B' then jumlah else 0 end) as TotalB,
tahun
from t
group by tahun;

Counting Null values in MYSQL

How do i count null values while making cross tab query?
I have a table with three colums [id, name, answer]
i have following records:
ID NAME ANS
1 ABC 1
1 ABC 0
1 ABC NULL
2 XYZ 1
2 XYZ NULL
2 XYZ NULL
2 XYZ 1
2 XYZ 0
1 ABC 0
now i would like to get my result:
ID Name NULLCOUNT TRUE COUNT FALSE COUNT
1 ABC 1 1 2
2 XYZ 2 2 1
I am using following SQL Statement:
select ID, NAME,
sum(case ANS when null then 1 else 0 end) as NULLCOUNT,
sum(case ANS when 1 then 1 else 0 end) as TRUECOUNT,
sum(case ANS when 0 then 1 else 0 end) as FALSECOUNT
from
TBL1
Group By ID, Name
Getting my result:
ID Name NULLCOUNT TRUE COUNT FALSE COUNT
1 ABC 0 1 2
2 XYZ 0 2 1
The NULL Count is getting error. Why and how can i solve this?
I believe instead of this:
sum(case ANS when null then 1 else 0 end) as NULLCOUNT
You should use this:
sum(case when ANS is null then 1 else 0 end) as NULLCOUNT
null -> is null?
NULL doesn't even compare with itself, you could use "CASE WHEN ANS is NULL"(you're also missing GROUP BY). Or try:
select ID, NAME,
sum(if(ans IS NULL, 1, 0)) as NULLCOUNT,
sum(case ANS when 1 then 1 else 0 end) as TRUECOUNT,
sum(case ANS when 0 then 1 else 0 end) as FALSECOUNT
from
TBL1
group by ID,NAME