如何按ID分组统计CNT:依据B.CO_ID是否为空筛选关联计数
解决方案
核心思路
你的需求本质是按A.ID分组后,优先统计该ID下存在B.CO_ID非空记录的CNT总和;若该ID没有任何B.CO_ID非空的记录,则统计所有CNT总和。关键是先判断每个ID的全局特征,再针对性执行求和逻辑。
方法一:使用EXISTS子查询(直观易懂)
在分组聚合时,通过子查询判断当前ID是否存在B.CO_ID非空的记录,再选择对应的求和规则:
SELECT A.ID, CASE -- 若当前ID存在B.CO_ID非空的记录,仅统计这些记录的CNT WHEN EXISTS ( SELECT 1 FROM your_table t2 WHERE t2.A.ID = t1.A.ID AND t2.B.CO_ID IS NOT NULL ) THEN SUM(CASE WHEN t1.B.CO_ID IS NOT NULL THEN t1.CNT ELSE 0 END) -- 若不存在,统计所有CNT ELSE SUM(t1.CNT) END AS SUM(CNT) FROM your_table t1 GROUP BY A.ID;
方法二:使用窗口函数(适合大数据量场景)
先通过窗口函数标记每个ID是否存在B.CO_ID非空的记录,再进行聚合计算:
SELECT DISTINCT A.ID, CASE WHEN has_valid_co_id = 1 THEN SUM(CASE WHEN B.CO_ID IS NOT NULL THEN CNT ELSE 0 END) OVER (PARTITION BY A.ID) ELSE SUM(CNT) OVER (PARTITION BY A.ID) END AS SUM(CNT) FROM ( SELECT *, -- 标记当前ID是否存在B.CO_ID非空的记录 MAX(CASE WHEN B.CO_ID IS NOT NULL THEN 1 ELSE 0 END) OVER (PARTITION BY A.ID) AS has_valid_co_id FROM your_table ) t;
你的CASE语句失败的常见原因
通常问题出在仅针对单行判断,未考虑整个分组的全局情况:比如单纯写SUM(CASE WHEN B.CO_ID IS NOT NULL THEN CNT ELSE 0 END),无法实现"只要分组里有CO_ID非空记录,就完全排除COUNTRY对应记录"的规则,而上面两种方法都是先判断分组的整体特征,再执行求和逻辑。
适配原表连接场景
如果你的数据集是由A、B两表连接得到的,可以直接把逻辑整合到原查询中,无需生成中间表:
SELECT A.ID, CASE WHEN EXISTS ( SELECT 1 FROM A a2 JOIN B b2 ON -- 替换为你原有的A、B表连接条件 WHERE a2.ID = A.ID AND b2.CO_ID IS NOT NULL ) THEN SUM(CASE WHEN B.CO_ID IS NOT NULL THEN CNT ELSE 0 END) ELSE SUM(CNT) END AS SUM(CNT) FROM A JOIN B ON -- 替换为你原有的连接条件 GROUP BY A.ID;
内容的提问来源于stack exchange,提问作者Be1ng_Kr1Sh
相关产品推荐
相关产品推荐

