MySQL with CASE WHEN with multiple values [duplicate] - mysql

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

Related

MySQL query to retrieve data based on date (sum of fields)

I'm new to MySQL so please be patient :)
I have a table where I would like to retrieve data based on date and do Sum
Here is my table
client datescanned problem title
abc 2019-02-02 12345a High xyz
abc 2019-02-02 12345b High xyz
abc 2019-02-02 12345c High xyz
abc 2019-02-02 12345d Medium xyz
abc 2019-02-09 12345e High xyz
abc 2019-02-09 12345f High xyz
abc 2019-02-09 12345g Low xyz
abc 2019-02-09 12345h Low xyz
abc 2019-02-09 12345j Low xyz
abc 2019-02-16 12345x High xyz
abc 2019-02-16 12345s High xyz
abc 2019-02-16 12345w High xyz
abc 2019-02-16 12345bs Medium xyz
My desired output would be
client datescanned problem High Medium Low
abc 2019-02-02 12345x 3 1 0
abc 2019-02-09 12345s 2 0 3
abc 2019-02-16 12345w 3 1 0
This is my code
select client,datescanned, problem, severity,
count(case when severity = 'High' then 1 end) as High,
count(case when severity = 'Medium' then 1 end) as Medium,
count(case when severity = 'Low' then 1 end) as Low
from ssstest where client = "myuser"
group by client,datescanned, problem
This will fetch all the numbers correctly, however I want to "sum" up High, Medium, Low per date.
Now I get..
client datescanned problem severity High Medium Low
abc 2019-02-02 12345a High 1 0 0
abc 2019-02-02 12345b High 1 0 0
abc 2019-02-02 12345c High 1 0 0
abc 2019-02-02 12345d Medium 0 1 0
abc 2019-02-09 12345e High 1 0 0
abc 2019-02-09 12345f High 1 0 0
abc 2019-02-09 12345g Low 0 0 1
abc 2019-02-09 12345h Low 0 0 1
abc 2019-02-09 12345j Low 0 0 1
abc 2019-02-16 12345x High 1 0 0
abc 2019-02-16 12345s High 1 0 0
abc 2019-02-16 12345w High 1 0 0
abc 2019-02-16 12345bs Medium 0 1 0
So basically, I just want to add up High, Medium, Low, group the same date together as one.
client datescanned problem High Medium Low
abc 2019-02-02 12345x 3 1 0
abc 2019-02-09 12345s 2 0 3
abc 2019-02-16 12345w 3 1 0
Thanks again for your help!
You can try using conditional aggregation
select client,dateadded, computername, severity,
count(case when severity='High' then 1 end) as High,
count(case when severity='Medium' then 1 end) as Medium,
count(case when severity='Low' then 1 end) as Low,
from mytable where client =%CURRENT_USER_LOGIN%
group by client,dateadded, computername
Update(1):
In MySQL/MariaDB query the following doesn't much sense:
=%CURRENT_USER_LOGIN%
If substring you are searching for is CURRENT_USER_LOGIN then use
like '%CURRENT_USER_LOGIN%'
select client,dateadded, computername, severity,
count(case when severity='High' then 1 end) as High,
count(case when severity='Medium' then 1 end) as Medium,
-- comma mark ',' before 'from' !!! produces error
count(case when severity='Low' then 1 end) as Low,
from mytable where client =%CURRENT_USER_LOGIN%
group by client,dateadded, computername

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.

Mimicking an excel pivot in SQL [duplicate]

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

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

COUNT added twice with JOIN Issue

I am working on project where I have reports that have three states its "checked","inprocess" and "completed"
Got two tables!
tbl_tracking - for keeping track of reports
report_id usr_id date status
----------------------------------------------
0000 abc 2014/04/05 checked
0001 abc 2014/04/05 checked
0000 abc 2014/04/05 inprocess
0001 abc 2014/04/05 completed
0002 abc 2014/04/06 completed
0004 xyz 2014/04/05 checked
0005 xyz 2014/04/06 checked
tbl_timestatus- for keeping track of time employees have worked on reports
usr_id date time_worked (hrs)
----------------------------------------------
abc 2014/04/05 6
abc 2014/04/06 5
Now I want to create a view to always display up-to-date status of everything so I code this
CREATE VIEW VW_STATUS AS
SELECT tb1.usr_id, tb1.date,
COUNT(CASE tb1.status WHEN 'checked' THEN 1 ELSE NULL END) AS checkedcount,
COUNT(CASE tb1.status WHEN 'inprocess' THEN 1 ELSE NULL END) AS inprocesscount,
COUNT(CASE tb1.status WHEN 'completed' THEN 1 ELSE NULL END) AS compltedcount,
CASE WHEN (tb1.usr_id=tb2.usr_id AND tb1.date=tb2.date) THEN tb2.time_worked ELSE NULL END AS timeworked
FROM tbl_tracking tb1, tbl_timestatus tb2
GROUP BY tb1.usr_id, tb1.date;
Expected Output:
usr_id date checkedcount inprocesscount completedcount timeworked
---------------------------------------------------------------------------------------
abc 2014/04/05 2 1 1 6
abc 2014/04/06 0 0 1 5
xyz 2014/04/05 1 0 0 NULL
xyz 2014/04/06 1 0 0 NULL
Actual Output:
usr_id date checkedcount inprocesscount completedcount timeworked
---------------------------------------------------------------------------------------
abc 2014/04/05 4 2 2 6
abc 2014/04/06 0 0 2 5
xyz 2014/04/05 2 0 0 NULL
xyz 2014/04/06 2 0 0 NULL
While the "timeworked" values remain correct, the count(*)'s add themselves twice!! There is some problem with join! Need help on same..
You should try like below. See a sample fiddle here http://sqlfiddle.com/#!3/0b24c/6
CREATE VIEW VW_STATUS AS
SELECT tb1.usr_id, tb1.date,
COUNT(CASE tb1.status WHEN 'checked' THEN 1 ELSE NULL END) AS checkedcount,
COUNT(CASE tb1.status WHEN 'inprocess' THEN 1 ELSE NULL END) AS inprocesscount,
COUNT(CASE tb1.status WHEN 'completed' THEN 1 ELSE NULL END) AS compltedcount,
tb2.time_worked
FROM tbl_tracking tb1
LEFT JOIN tbl_timestatus tb2
ON tb1.usr_id=tb2.usr_id
AND tb1.date=tb2.date
GROUP BY tb1.usr_id, tb1.date , tb2.time_worked
ORDER BY tb1.usr_id;
Which results in
join tbl1 and tb2 on tb1.usr_id=tb2.usr_id AND tb1.date=tb2.date. Note that the time worked is correct.