NOT EXISTS
1.NOT EXISTS
是 SQL 中用于关联性子查询过滤数据的关键操作符,其核心意义是检查主表的每一行是否不存在于子查询的结果中。
NOT EXISTS
对主表的每一行数据,检查子查询是否没有返回任何结果。如果子查询为空,则保留该行;否则过滤掉该行。
逻辑:
NOT EXISTS (子查询)
-- 等价于 --
主表行数据 ∉ 子查询结果集
例子:
SELECT *
FROM 主表 t1
WHERE label = 0
AND NOT EXISTS (
SELECT 1
FROM 黑名单表 t2
WHERE t2.customer_id = t1.customer_id -- 关联条件
);
执行步骤:
-
遍历主表
数据库逐行扫描主表(t1
),只处理label=0
的行。 -
触发子查询
对主表的每一行,执行子查询:- 将当前行的
t1.customer_id
代入子查询的条件中(t2.customer_id = t1.customer_id
)。
- 将当前行的
-
检查子查询结果
- 如果子查询找到至少一条匹配记录 →
NOT EXISTS
返回false
→ 过滤掉主表的当前行。 - 如果子查询未找到任何匹配记录 →
NOT EXISTS
返回true
→ 保留主表的当前行。
- 如果子查询找到至少一条匹配记录 →
-
提前终止机制
子查询一旦找到第一条匹配记录,立即停止扫描。例如,若黑名单表中有100条相同的customer_id=A
,子查询只需找到第一条即可确认存在。
NOT IN
SELECT *
FROM 主表
WHERE label = 0
AND customer_id NOT IN (
SELECT DISTINCT customer_id
FROM black
);
存在问题:子查询生成所有黑名单 customer_id
列表,主表需要全表扫描逐个排除,效率低。
"Not in"是一种用于查询的运算符,用于在某个列中查找不包含指定值或列表的。
区别
NOT EXISTS 比NOT IN在大型数据场景可以快一倍