SQL计数和条件分组

时间:2016-04-07 11:35:21

标签: sql postgresql

在我的postgresql数据库中,我有一个分数表,其中包含user_id,item_id,succeeded(bool)和created_at。

我想计算每个用户和每个项目的成功项目数(成功的地方=' t')。但我只想计算最后一次失败后发生的成功项目。

我尝试以下代码但没有成功。

SELECT COUNT(*), item_id
FROM score
WHERE score.succeeded = 't' AND user_id = XX 
GROUP BY score.item_id 
HAVING MAX(score.created_at) > score.created_at AND score.succeeded = 'f'

为例

数据:

user_id | item_id | succeeded | created_at
------------------------------------------
12      | 1       | true      | 2016-04-01
12      | 1       | false     | 2016-04-02
12      | 1       | true      | 2016-04-03

12      | 2       | true      | 2016-04-01
12      | 2       | true      | 2016-04-02
12      | 2       | true      | 2016-04-03

12      | 3       | true      | 2016-04-01
12      | 3       | true      | 2016-04-02
12      | 3       | false     | 2016-04-03

例外结果(针对用户12):

item_id | succeeded_count
-------------------------
1       | 1
2       | 3
3       | 0

2 个答案:

答案 0 :(得分:2)

添加<div></div>条件。它将确保只计算没有后来假行的真行。

NOT EXISTS

答案 1 :(得分:0)

您应该过滤where子句中的行。假设succeeded仅采用'f''t'的值:

select s.item_id, count(*)
from score s
where s.created_at > (select max(s2.created_at)
                      from score s2
                      where s2.item_id = s.item_id and s2.succeeded = 'f'
                     )
group by s.item_id;

注意:这会过滤掉0的值。您可以使用join取代所有这些:

select s.item_id, count(s2.item_id)
from scores s left join
     (select item_id, max(created_at) maxca
      from scores
      where succeeded = 'f'
      group by item_id
     ) ss
     on s.item_id = ss.item_id and s.created_at >= ss.maxca
group by item_id;

如果succeeded可以使用'f'以外的值,则可以向外部查询添加where子句或使用条件聚合。