SQL - 使用“min”和groupby进行过滤

时间:2018-02-20 17:27:02

标签: sql postgresql

我想提出一个查询,它与过滤器一起进行“min”计算(status ='PENDING'),以便返回正确的 min_id 。简单地在where子句中添加它不会解决我的目的。使用以下信息可能更容易理解:

Table: 

  id    sub_id         status      il_flag

  21     889          FAILED       false
  22     889          PENDING      false
  23     889          PENDING      false

更改为MyQuery:

select sub_id, 
       min(id) as min_id, 
       sum(case when status = 'PENDING' then 1 else 0 end) as pending_count,
       sum(case when status in ('ACCEPTED','FAILED') then 1 else 0 end) as invalid_count
    from sub_event where il_flag=false
    group by sub_id

以上查询的结果(返回错误'min_id'):

sub_id  min_id  valid_count  invalid_count
 889      21       2            1  

预期结果(状态的最小ID ='待定'):

sub_id  min_id  valid_count  invalid_count
 889      22       2            1  

在上面的查询中,只需在“ where ”子句中添加“status ='PENDING'”就无法解决我的目的,因为我们不会得到 invalid_count

我正在使用postgres 9.6

提前致谢!

1 个答案:

答案 0 :(得分:2)

使用条件聚合:

  min(case when status = 'PENDING' then id end) as min_pending_id,

或者,更好的是,使用filter

min(id) filter (where status = 'PENDING')

后者在Postgres 9.4中引入,与大多数其他数据库不兼容,并且应该具有稍​​好的性能(它与ANSI标准一致)。

编辑:

实际上,您可以将整个查询编写为:

select sub_id, 
       min(id) filter (where status = 'PENDING') as min_id, 
       count(*) filter (where status = 'PENDING') as pending_count,
       count(*) filter (where status in ('ACCEPTED', 'FAILED')) as invalid_count
from subscription_event
where idl_flag = false
group by sub_id;

我使用filter子句越多,我就越喜欢它。切勿再次在聚合中使用case