I have a MySQL table:
create table tbl (
amount int
);
insert into tbl (amount) values (1);
insert into tbl (amount) values (2);
insert into tbl (amount) values (3);
insert into tbl (amount) values (4);
My goal is a report of how many values are in the following buckets, by using a case statment.
Bucket A: values 0-1
Bucket B: values 2-5
Bucket C: values 6-9
First lets try a simple query:
select "Bucket A" as Bucket, count(amount) "Count"
from tbl
where amount in (0,1)
union
select "Bucket B" as Bucket, count(amount) "Count"
from tbl
where amount in (2,3,4,5)
union
select "Bucket C" as Bucket, count(amount) "Count"
from tbl
where amount in (6,7,8,9);
Result:
+----------+-------+
| Bucket | Count |
+----------+-------+
| Bucket A | 1 |
| Bucket B | 3 |
| Bucket C | 0 |
+----------+-------+
Results are perfect, but I want a case statement.
So I try this:
select
sum(case when amount in (0,1) then 1 else 0 end) as "Bucket A",
sum(case when amount in (2,3,4,5) then 1 else 0 end) as "Bucket B",
sum(case when amount in (6,7,8,9) then 1 else 0 end) as "Bucket C"
from tbl;
Result:
+----------+----------+----------+
| Bucket A | Bucket B | Bucket C |
+----------+----------+----------+
| 1 | 3 | 0 |
+----------+----------+----------+
Values are correct, and great that I have a case statement, but problem is the values got pivoted.
How can I
1. use a case statement
2. have no pivot?
You can do this using aggregation:
select (case when amount in (0, 1) then 'Bucket A'
when amount in (2, 3,4, 5) then 'Bucket B'
when amount in (6, 7, 8, 9) then 'Bucket C'
end) as bucket, count(*) as `count`
from tbl
where amount in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
group by (case when amount in (0, 1) then 'Bucket A'
when amount in (2,3,4,5) then 'Bucket B'
when amount in (6,7,8,9) then 'Bucket C'
end);
EDIT:
Digital Chris makes a very good point. This can be solved by using left outer join
:
select (case when tbl.amount in (0, 1) then 'Bucket A'
when tbl.amount in (2, 3,4, 5) then 'Bucket B'
when tbl.amount in (6, 7, 8, 9) then 'Bucket C'
end) as bucket, count(tbl.amount) as `count`
from (select 0 as amount union all
select 2 as amount union all
select 6 as amount
) throwaway left outer join
tbl
on throwaway.amount = tbl.amount
where tbl.amount in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
group by (case when tbl.amount in (0, 1) then 'Bucket A'
when tbl.amount in (2,3,4,5) then 'Bucket B'
when tbl.amount in (6,7,8,9) then 'Bucket C'
end);
Or, perhaps more clearly, by using the original query as a subquery:
select buckets.bucket, coalesce(`count`, 0) as `count`
from (select 'Bucket A' as bucket union all
select 'Bucket B' union all
select 'Bucket C'
) buckets left outer join
(select (case when amount in (0, 1) then 'Bucket A'
when amount in (2, 3,4, 5) then 'Bucket B'
when amount in (6, 7, 8, 9) then 'Bucket C'
end) as bucket, count(*) as `count`
from tbl
where amount in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
group by (case when amount in (0, 1) then 'Bucket A'
when amount in (2,3,4,5) then 'Bucket B'
when amount in (6,7,8,9) then 'Bucket C'
end)
) g
on buckets.bucket = g.bucket;
select
"Bucket A" as "Bucket", sum(case when amount in (0,1) then 1 else 0 end) as "Count" from tbl
UNION
select "Bucket B", sum(case when amount in (2,3,4,5) then 1 else 0 end) from tbl
UNION
select "Bucket C", sum(case when amount in (6,7,8,9) then 1 else 0 end) from tbl;
Like this? sqlfiddle
SELECT "Bucket A" AS Bucket ,
(SELECT SUM(CASE WHEN amount IN (0,1) THEN 1 ELSE 0 END) FROM tbl) AS "COUNT"
UNION
SELECT "Bucket B" AS Bucket ,
(SELECT SUM(CASE WHEN amount IN (2,3,4,5) THEN 1 ELSE 0 END) FROM tbl) AS "COUNT"
UNION
SELECT "Bucket C" AS Bucket ,
(SELECT SUM(CASE WHEN amount IN (6,7,8,9) THEN 1 ELSE 0 END) FROM tbl) AS "COUNT"
Use a manufactured list of bucket names, then left join to the table:
select concat('Bucket ', b) bucket, count(amount) count
from (select 'A' as b union select 'B' union select 'C') a
left join tbl on b =
case when amount in (0, 1) then 'A'
when amount in (2,3,4,5) then 'B'
when amount in (6,7,8,9) then 'C' end
group by 1
This will produce a row with a zero count when no rows for the bucket are found.
See SQLFiddle
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.