SQL查询:存在指定content值时排除对应客户端全部数据
需求说明
现有业务表包含client_id、content两个字段,单个client_id平均对应50条左右的content记录。
原过滤逻辑where content NOT IN ('2','3','4')仅剔除了content值为'2'、'3'、'4'的单条记录,仍会返回对应client的其余行,不符合预期。
目标逻辑:只要某个client_id下存在任意一条content取值为'2'、'3'、'4'的记录,就完全过滤掉该client_id关联的所有数据。
可落地的SQL写法
以下三种写法都能实现需求,优先推荐第一种NOT EXISTS写法,兼容绝大多数数据库,且在有索引的场景下性能最优:
- 写法1:NOT EXISTS 关联子查询
SELECT a.client_id, a.content FROM 你的业务表名 a WHERE NOT EXISTS ( SELECT 1 FROM 你的业务表名 b WHERE b.client_id = a.client_id AND b.content IN ('2','3','4') );
- 写法2:LEFT JOIN 空值判断
逻辑和NOT EXISTS完全等价,部分老旧数据库版本下执行效率表现稳定:
SELECT a.client_id, a.content FROM 你的业务表名 a LEFT JOIN 你的业务表名 b ON a.client_id = b.client_id AND b.content IN ('2','3','4') WHERE b.client_id IS NULL;
- 写法3:先聚合排除目标client_id再匹配
写法最直观,但注意如果子查询返回的client_id存在NULL值,NOT IN会出现结果异常,使用前需确认client_id字段为非空属性:
SELECT client_id, content FROM 你的业务表名 WHERE client_id NOT IN ( SELECT DISTINCT client_id FROM 你的业务表名 WHERE content IN ('2','3','4') );
优化提示:如果表数据量较大,建议创建
(client_id, content)的联合索引,能大幅降低上述查询的扫描行数,提升执行速度。
内容的提问来源于stack exchange,提问作者Nickname_used
相关产品推荐
相关产品推荐

