在MySQL中,如何使用case语句重写查询?

在MySQL中,如何使用case语句重写查询?,mysql,sql,Mysql,Sql,我有一个MySQL表: 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); 我的目标是通过使用case语句报告以下存储桶中有多少个值 桶A:值0-1 桶B:值2-5 桶C:值6-9

我有一个MySQL表:

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);
我的目标是通过使用case语句报告以下存储桶中有多少个值

桶A:值0-1
桶B:值2-5
桶C:值6-9

首先,让我们尝试一个简单的查询:

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);
结果:

+----------+-------+
| Bucket   | Count |
+----------+-------+
| Bucket A |     1 |
| Bucket B |     3 |
| Bucket C |     0 |
+----------+-------+
+----------+----------+----------+
| Bucket A | Bucket B | Bucket C |
+----------+----------+----------+
|        1 |        3 |        0 |
+----------+----------+----------+
结果是完美的,但我想要一个案例陈述
所以我试着这样做:

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;
结果:

+----------+-------+
| Bucket   | Count |
+----------+-------+
| Bucket A |     1 |
| Bucket B |     3 |
| Bucket C |     0 |
+----------+-------+
+----------+----------+----------+
| Bucket A | Bucket B | Bucket C |
+----------+----------+----------+
|        1 |        3 |        0 |
+----------+----------+----------+
值是正确的,我有一个case语句,这很好,但问题是这些值被旋转了

我怎样才能
1.使用案例陈述

2.没有支点

您可以使用聚合进行此操作:

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);
编辑:

Digital Chris提出了一个很好的观点。这可以通过使用左外连接解决:

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);
或者,更清楚地说,使用原始查询作为子查询:

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 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
当找不到存储桶的行时,这将生成一个计数为零的行


请参见

是否有任何方法可以通过编程确定哪个桶有哪个
金额
,或者您只需要使用这些值?我想我需要使用我在问题中提供的值。这不会给您“桶C,0”@DigitalChris的记录。说得好。不过,解决这个问题确实会使查询更加复杂。