How get TOP from query? [duplicate] - mysql

This question already has answers here:
Is there an alternative to TOP in MySQL?
(4 answers)
Closed 6 years ago.
SELECT
user_id,
count(*) total,
sum(case when type = 'yes' then 1 else 0 end) as type_1,
sum(case when type = 'no' then 1 else 0 end) as type_2
FROM history
GROUP by user_id
How get TOP 100 rows from this query which have max count type = 'yes' ?

You can use LIMIT to limit the number of results and use an ORDER BY to order it so the results are in descending order of total.
SELECT
user_id,
count(*) total,
sum(case when type = 'yes' then 1 else 0 end) as type_1,
sum(case when type = 'no' then 1 else 0 end) as type_2
FROM history
GROUP by user_id
ORDER BY type_1 DESC
LIMIT 100

You should add WHERE statement to your query to add conditional statement
Also, I can see that you are using mysql, so that means you should order your data by argument descending and limit result to 100
SELECT
user_id,
count(*) total,
sum(case when type = 'yes' then 1 else 0 end) as type_1,
sum(case when type = 'no' then 1 else 0 end) as type_2
FROM history
WHERE type='yes'
GROUP by user_id
ORDER BY total DESC
LIMIT 100

SELECT
user_id,
count(*) total,
sum(case when type = 'yes' then 1 else 0 end) as type_1,
sum(case when type = 'no' then 1 else 0 end) as type_2
FROM history
GROUP by user_id
ORDER by type_1 DESC
LIMIT 100

Related

Why are my various CASE WHEN functions returning the same values?

Im trying to write a query that returns a count depending on the value of a feedback field that ranges from 0-5 (0 meaning that it was not rated).
I want:
Count of all rows ( anything rated 1 or greater)
Count of all rows rated as 1 (anything = 1)
And all rows rated as 1 and also is the first iteration of a given task (anything rated =1 and iteration = 0)
I have written this query but I am getting the same value for all counts:
select
DATE_FORMAT(created_at,'%M') as Month,
COUNT(CASE WHEN rate > 0 THEN 1 ELSE 0 END) AS total,
COUNT(CASE WHEN rate = 1 THEN 1 ELSE 0 END) AS Rated_1,
COUNT(CASE WHEN client_feedback = 1 AND index = 0 THEN 1 ELSE 0 END) AS first_iteration_rated_1
from tablexxx
where created_at between date('2022-04-01') and date('2022-10-01')
GROUP BY Month
Try to use SUM() instead of COUNT().
Count() will count up regardless of the value being 0 or 1.
you can have two approaches:
method 1: use NULL in else part of the CASE
select
DATE_FORMAT(created_at,'%M') as Month,
COUNT(CASE WHEN rate > 0 THEN 1 ELSE null END) AS total,
COUNT(CASE WHEN rate = 1 THEN 1 ELSE null END) AS Rated_1,
COUNT(CASE WHEN client_feedback = 1 AND index = 0 THEN 1 ELSE null END) AS first_iteration_rated_1
from tablexxx
where created_at between date('2022-04-01') and date('2022-10-01')
GROUP BY Month
method 2: use sum instead of count
select
DATE_FORMAT(created_at,'%M') as Month,
SUM(CASE WHEN rate > 0 THEN 1 ELSE 0 END) AS total,
SUM(CASE WHEN rate = 1 THEN 1 ELSE 0 END) AS Rated_1,
SUM(CASE WHEN client_feedback = 1 AND index = 0 THEN 1 ELSE 0 END) AS first_iteration_rated_1
from tablexxx
where created_at between date('2022-04-01') and date('2022-10-01')
GROUP BY Month

Count different values in a column, while doing total and group by different column values

We have a table with data from different nodes and one of the column will have status report as "compliant or non-compliant", sample data as below
I want to filter the table in such a way that if any of the checks on a node shows non compliant, it should be flagged as non-compliant and rest as compliant. Using below query i am able to do it
SELECT COUNT(*) AS total_nodes,
SUM(fully_compliant = 0) AS Non_compliant_nodes,
SUM(fully_compliant = 1) AS compliant_nodes
FROM (
SELECT Node, CASE WHEN SUM(Status = 'Compliant') = COUNT(*) THEN 1 ELSE 0 END AS fully_compliant
FROM your_table GROUP BY Node
)
Now, i want to group and split the result by dept as below, how can i achieve this
I think you're looking for this:
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
sum(case when 'Non-Compliant' then 1 else 0 end) as non_compliant_chk
from your_table
group by dept,
node
) v
group by dept;
With few modifications to what Brian suggested, I am able to get the desired result
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
COUNT(CASE WHEN Compliance-Status = 'Non-Compliant' THEN 1 END) 'non_compliant_chk'
from table WHERE DOR >= DATE(NOW()) - INTERVAL 7 DAY
group by Dept,
Node
) v
group by Dept;

i want MySQL query result in same row

SELECT sum(case when (gender)=1 THEN 1 ELSE 0 END),
GROUP_CONCAT(sum(case when (gender)=2 THEN 1 ELSE 0 END) SEPARATOR ' ') as combine
from family_member_tbl
GROUP BY gender
NO, you can't nest grouping function like that. Rather get the sum first and then group_concat() like
select sum_1, sum_2, group_concat(sum_2) as combine
from (
SELECT gender,
sum(case when gender = 1 THEN 1 ELSE 0 END) as sum_1,
sum(case when gender = 2 THEN 1 ELSE 0 END) as sum_2
from family_member_tbl
GROUP BY gender ) xxx
group by gender;

SQL using CASE in count and group by

I'm using CASE to categorize data in the table and count them but the results aren't accurate
live demo [here]
select DATE(date) as day, count(*),
count(distinct case when name = 'fruit' then 1 else 0 end) as fruits,
count(distinct case when name = 'vege' then 1 else 0 end) as vege,
count(distinct case when name = 'sweets' then 1 else 0 end) as sweets
from food
group by day
with rollup
I'm not sure if the issue is with CASE or in the string matching = because there's no 'sweets' still it counts 1?
any pointers I'd be grateful
Your problem is that COUNT counts every result that is not NULL. In your case you are using:
COUNT(distinct case when name = 'sweets' then 1 else 0 end)
So, when the name is not sweets, it counts the 0. Furthermore, since you are using DISTINCT, it counts just one or two values. You should either use SUM or remove the DISTINCT and the ELSE 0:
SELECT DATE(date) as day,
COUNT(*),
SUM(CASE WHEN name = 'fruit' THEN 1 ELSE 0 END) as fruits,
SUM(CASE WHEN name = 'vege' THEN 1 ELSE 0 END) as vege,
SUM(CASE WHEN name = 'sweets' THEN 1 ELSE 0 END) as sweets
FROM food
GROUP BY DAY
WITH ROLLUP
Or:
SELECT DATE(date) as day,
COUNT(*),
COUNT(CASE WHEN name = 'fruit' THEN 1 ELSE NULL END) as fruits,
COUNT(CASE WHEN name = 'vege' THEN 1 ELSE NULL END) as vege,
COUNT(CASE WHEN name = 'sweets' THEN 1 ELSE NULL END) as sweets
FROM food
GROUP BY DAY
WITH ROLLUP
Here is a modified sqlfiddle.
You can't group by an alias. You have to group by the expression.
group by date(date)
You can group on an Alias:
SELECT
FROM_UNIXTIME(UnixTimeField, '%Y') AS 'Year'
,FROM_UNIXTIME(UnixTimeField, '%m') AS 'Month'
FROM table p
GROUP BY Year, Month

Getting total value from each field?

How do I get the Total value of Yes, No, Other fields of each username?
I like to add Total field.
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE NULL END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE NULL END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE NULL END) as Other
//How to get total of Yes/No/Other
FROM table
WHERE source = 'CompanyName' ";
Also the highest Total goes at the top order.
use 0 instead of NULL, add the missing group by and use COUNT(*) to get the total of each group and order the result:
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE 0 END) as Other,
COUNT(*) as TOTAL
FROM table
WHERE source = 'CompanyName'
group by Username
order by TOTAL desc;
This assumes that type can only be 'Yes', 'No' or ''.
Use a sub query to sum up your results and add a sort:
select yes, no, other, yes + no + other as Total
from (
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE 0 END) as Other
FROM table
WHERE source = 'CompanyName'
)
order by (yes + no + other) desc
Don't use SUM(null), the SUM of (1,1,1,null) = null, not 3.
SELECT s.*, s.yes+s.no+s.other as all FROM (
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE 0 END) as Other
FROM table
WHERE source = 'CompanyName'
GROUP BY Username
) s
ORDER BY all DESC