我想提出一个查询,它与过滤器一起进行“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
提前致谢!
答案 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
!