SQL查询问题:筛选双1条件ID数据,排除含双0的ID
适配GROUP BY + HAVING方法解决你的SQL需求
当然可以把那位用户的GROUP BY + HAVING思路适配到你的需求里!咱们先把你的需求再明确一遍:
- 要获取所有
joi.processed = 1且joi.approved = 1的行 - 但如果某个
id(也就是oa.id/kio.id_table_1)下存在任何一行joi.processed = 0且joi.approved = 0的记录,就完全排除这个id的所有数据
先理解原方法的核心逻辑
那位用户的思路是通过GROUP BY分组后,用SUM(条件)来统计分组内符合特定规则的行数:
SUM(col3=1) > 0:确保分组里至少有一行col3=1SUM(col3=2) > 0:确保分组里至少有一行col3=2SUM(col3 not in (1,2)) = 0:确保分组里完全没有col3不在{1,2}的行
这个思路完全可以平移到你的场景,只是要把条件换成你的业务规则。
适配到你的需求的实现方案
我们需要先筛选出符合要求的id,再基于这些id获取具体的行。这里提供两种写法:
写法1:用子查询+GROUP BY HAVING筛选id
SELECT * FROM table1 oa INNER JOIN table2 kio ON oa.id = kio.id_table_1 INNER JOIN table3 joi ON kio.col3 = joi.col3_id_table_2 WHERE oa.id IN ( -- 子查询先找出符合要求的id:有目标行,且无排除行 SELECT oa_inner.id FROM table1 oa_inner INNER JOIN table2 kio_inner ON oa_inner.id = kio_inner.id_table_1 INNER JOIN table3 joi_inner ON kio_inner.col3 = joi_inner.col3_id_table_2 GROUP BY oa_inner.id HAVING -- 确保该id下至少有一行符合processed=1且approved=1 SUM(joi_inner.processed = 1 AND joi_inner.approved = 1) > 0 -- 确保该id下完全没有processed=0且approved=0的行 AND SUM(joi_inner.processed = 0 AND joi_inner.approved = 0) = 0 ) -- 外层再过滤出目标行(避免拿到该id下其他不符合的行) AND joi.processed = 1 AND joi.approved = 1;
写法2:用NOT EXISTS更直观判断
如果你觉得子查询分组有点绕,也可以用NOT EXISTS直接检查当前id是否存在要排除的行:
SELECT * FROM table1 oa INNER JOIN table2 kio ON oa.id = kio.id_table_1 INNER JOIN table3 joi ON kio.col3 = joi.col3_id_table_2 WHERE joi.processed = 1 AND joi.approved = 1 -- 排除存在processed=0且approved=0行的id AND NOT EXISTS ( SELECT 1 FROM table3 joi_exclude INNER JOIN table2 kio_exclude ON joi_exclude.col3_id_table_2 = kio_exclude.col3 WHERE kio_exclude.id_table_1 = oa.id AND joi_exclude.processed = 0 AND joi_exclude.approved = 0 );
为什么原方法适用?
本质上,你和那位用户的需求都是基于分组(或同一id集合)的规则校验:
- 那位用户要确保分组内只有指定值
- 你要确保分组内没有特定的(processed, approved)组合,同时存在目标组合
SUM(条件)的核心是把满足条件的行计数为1,不满足的为0,求和后就能判断分组内是否存在这类行——这个逻辑是通用的,完全可以迁移过来。
内容的提问来源于stack exchange,提问作者user7989054
相关产品推荐
相关产品推荐

