MySQL不支持MINUS/EXCEPT时,如何查询仅含a类型不含b类型的人员
解决MySQL中查询拥有a类型但无b类型人员的问题
嘿,这个场景我之前在项目里也碰到过,确实MySQL不像部分数据库那样支持MINUS/EXCEPT语法,但咱们有好几种靠谱的替代方案,我给你详细说说:
方法一:使用NOT EXISTS子查询(最直观)
思路很直接:先筛选出所有拥有a类型的人员,再排除掉那些同时拥有b类型的人。
SELECT DISTINCT p.person FROM Person p WHERE p.type = 'a' AND NOT EXISTS ( SELECT 1 FROM Person p2 WHERE p2.person = p.person AND p2.type = 'b' );
- 加
DISTINCT是因为同一个人可能有多条a类型的记录,去重后得到唯一的人员列表; NOT EXISTS会针对每一条a类型的记录,检查该人员是否存在b类型的记录,不存在则保留这条结果。
方法二:使用LEFT JOIN + IS NULL
通过左关联的方式,把a类型的记录和b类型的记录关联起来,筛选出关联不上b类型的人员(也就是没有b类型的)。
SELECT DISTINCT p.person FROM Person p LEFT JOIN Person p2 ON p.person = p2.person AND p2.type = 'b' WHERE p.type = 'a' AND p2.person IS NULL;
LEFT JOIN会保留所有p表中a类型的记录,对于没有对应b类型的人员,p2表的字段会是NULL;- 筛选
p2.person IS NULL就能得到只拥有a类型的人员。
方法三:使用GROUP BY + HAVING统计
通过分组统计每个人员的类型情况,直接筛选出符合条件的人员。
SELECT person FROM Person GROUP BY person HAVING SUM(CASE WHEN type = 'a' THEN 1 ELSE 0 END) > 0 AND SUM(CASE WHEN type = 'b' THEN 1 ELSE 0 END) = 0;
GROUP BY person把数据按人员分组;- 用
CASE语句分别统计每个人员拥有a类型和b类型的次数,要求a类型次数大于0(至少有一个a),b类型次数等于0(完全没有b)。
小提示
如果你的表数据量比较大,建议给person和type字段建立联合索引,这三种方法的性能都会提升不少。其中NOT EXISTS和LEFT JOIN的性能通常会优于GROUP BY方案,具体可以根据你的实际数据情况测试。
内容的提问来源于stack exchange,提问作者user9314692
相关产品推荐
相关产品推荐

