SQL分组时如何同时计算总违规数与已通过项的违规数总和?
解决同一分组查询中同时计算多条件聚合值的问题
首先整理你的表结构,方便查看:
VIDEO_ID DATETIME APPROVED VIOLATION_COUNT VIDEO_DESCRIPTION VIDEO1 2018-01-02 yes 1 a VIDEO2 2018-06-02 no 2 b VIDEO3 2018-07-04 yes 1 c VIDEO4 2018-01-12 yes 1 b VIDEO5 2018-06-02 no 2 c VIDEO6 2018-07-29 yes 1 a
你的核心需求是按VIDEO_TYPE(通过VIDEO_DESCRIPTION用CASE语句判定)分组,同时计算两个聚合值:
- 每个
VIDEO_TYPE的VIOLATION_COUNT总和 - 仅当
APPROVED = 'yes'时的VIOLATION_COUNT总和
为什么你的原查询报错?
你写的子查询(select count(APPROVED) where APPROVED = 'yes')存在两个关键问题:
- 子查询没有和外层分组建立关联,数据库无法识别它应该对应当前分组的行
- 你误用了
count()函数——你需要的是求和而非计数,而且要精准筛选APPROVED='yes'的行进行求和
正确方案:使用条件聚合
我们可以直接在同一SELECT语句中,用SUM()结合CASE语句实现条件聚合,完全不需要子查询:
SELECT CASE WHEN VIDEO_DESCRIPTION = 'a' THEN 'Video type 1' WHEN VIDEO_DESCRIPTION = 'b' THEN 'Video type 2' WHEN VIDEO_DESCRIPTION = 'c' THEN 'Video type 3' ELSE 'Others' END AS VIDEO_TYPE, SUM(VIOLATION_COUNT) AS 总VIOLATION_COUNT, SUM(CASE WHEN APPROVED = 'yes' THEN VIOLATION_COUNT ELSE 0 END) AS APPROVED_YES_VIOL_COUNT FROM my_table GROUP BY VIDEO_TYPE;
逻辑说明
SUM(VIOLATION_COUNT):对每个分组下所有行的VIOLATION_COUNT直接求和,得到该类型的总违规数SUM(CASE WHEN APPROVED = 'yes' THEN VIOLATION_COUNT ELSE 0 END):
逐行判断APPROVED是否为yes,符合条件就取对应的VIOLATION_COUNT,不符合则取0,最后对这些值求和,精准得到仅通过审核的视频的违规数总和
测试结果
用你的表数据运行该查询,会得到如下结果:
VIDEO_TYPE 总VIOLATION_COUNT APPROVED_YES_VIOL_COUNT Video type 1 2 2 Video type 2 3 1 Video type 3 3 1
这样就完美实现了你需要的两个聚合计算,同时避免了子查询带来的关联问题。
内容的提问来源于stack exchange,提问作者Bilberryfm
相关产品推荐
相关产品推荐

