如何用LEFT JOIN和IS NULL筛选出仅存在于A表且不存在于B表的数据?
- 内容介绍
- 相关推荐
本文共计1043个文字,预计阅读时间需要5分钟。
直接使用 `LEFT JOIN 连接 A 表和 B 表,再用 `WHERE B.id IS NULL` 筛选 A 表中独有的记录。这是 SQL 标准做法,兼容 MySQL、PostgreSQL、SQL Server、Oracle 等主流数据库。它不依赖于子查询优化器,执行计划稳定,尤其在 B 表有合适索引时性能优越。
常见错误是写成 WHERE B.id = NULL —— 这永远不成立,因为 NULL = NULL 返回 UNKNOWN,不是 TRUE,必须用 IS NULL。
- JOIN 条件要基于业务主键或唯一关联字段(如
ON a.user_id = b.user_id),别用模糊字段(如 name) - 如果 B 表连接字段允许 NULL,
IS NULL会把 B 表本就为 NULL 的行也误判为“不存在”,需提前确认 B 表该字段是否定义为NOT NULL - 若 A 表有重复数据,结果也会重复;需要去重可加
DISTINCT,但更推荐先厘清业务语义是否允许重复
为什么不用 NOT IN?它在 NULL 场景下会失效
NOT IN 看似简洁,但只要 B 表的对比字段(如 b.id)中存在任意一个 NULL,整个查询就会返回空结果集。
本文共计1043个文字,预计阅读时间需要5分钟。
直接使用 `LEFT JOIN 连接 A 表和 B 表,再用 `WHERE B.id IS NULL` 筛选 A 表中独有的记录。这是 SQL 标准做法,兼容 MySQL、PostgreSQL、SQL Server、Oracle 等主流数据库。它不依赖于子查询优化器,执行计划稳定,尤其在 B 表有合适索引时性能优越。
常见错误是写成 WHERE B.id = NULL —— 这永远不成立,因为 NULL = NULL 返回 UNKNOWN,不是 TRUE,必须用 IS NULL。
- JOIN 条件要基于业务主键或唯一关联字段(如
ON a.user_id = b.user_id),别用模糊字段(如 name) - 如果 B 表连接字段允许 NULL,
IS NULL会把 B 表本就为 NULL 的行也误判为“不存在”,需提前确认 B 表该字段是否定义为NOT NULL - 若 A 表有重复数据,结果也会重复;需要去重可加
DISTINCT,但更推荐先厘清业务语义是否允许重复
为什么不用 NOT IN?它在 NULL 场景下会失效
NOT IN 看似简洁,但只要 B 表的对比字段(如 b.id)中存在任意一个 NULL,整个查询就会返回空结果集。

