0

我有一个订单表。

+----------+--------+---------+
| order_id |  city  | status  |
+----------+--------+---------+
|        1 | NYC    | success |
|        2 | London | failure |
|        3 | Tokyo  | success |
|        4 | NYC    | failure |
|        5 | London | failure |
|        6 | Tokyo  | success |
|        7 | NYC    | success |
|        8 | London | failure |
|        9 | Tokyo  | success |
|       10 | NYC    | failure |
+----------+--------+---------+

我想编写一个查询以根据其失败率按升序列出所有城市。

城市失败率=(城市失败订单)*100/(城市订单总数)

上表的查询输出应为:

+--------+--------------+
|  city  | failure_rate |
+--------+--------------+
| Tokyo  |            0 |
| NYC    |           50 |
| London |          100 |
+--------+--------------+

现在,作为一个菜鸟,我只能编写查询来获取按城市分组的失败订单数和按城市分组的总订单数,如下所示:

select city, count(order_id) as failed
from orders
where status='failure'
group by city
order by failed asc;

select city, count(order_id) as total
from orders
group by city
order by total asc;

但我无法编写查询以获得所需的结果。

4

3 回答 3

2
select city, 
       sum(case when status='failure' then 1 else 0 end) * 100 / count(*) as rate
from orders
group by city
order by rate asc;
于 2020-09-27T06:09:18.573 回答
1

我们可以filter根据相同的条件使用多个计数group by

select c.*,(failed*100)/total failure_rate
  from (select city
              ,count(*) total
              ,count(order_id) filter (where status='failure') failed
          from orders
        group by city
       ) c
order by failed
于 2020-09-27T06:30:02.670 回答
1

我喜欢avg()用于这个目的。在通用 SQL 中:

select city, 
       avg(case when status = 'failure' then 1.0 else 0 end) as fail_rate
from orders
group by city
order by fail_rate asc;

也可以根据数据库简化计算。例如,在 MySQL 中:

       avg( status = 'failure' ) as fail_rate

在 Postres/Redshift 中:

       avg( (status = 'failure')::int ) as fail_rate
于 2020-09-27T13:27:57.873 回答