首页/数据/SQL 速查/INTERSECT 与 EXCEPT 交集/差集

INTERSECT 与 EXCEPT 交集/差集

标准集合运算:INTERSECT 取两查询都有的行,EXCEPT 取前一查询有而后一查询没有的行,默认都去重。

SQL 速查数据更新于 2026-10-13

两个集合运算符

INTERSECT 取两个查询都有的行,EXCEPT 取前一个查询有、后一个查询没有的行,两者默认都去重,属于 SQL 标准集合运算。MySQL 从 8.0.31 才开始支持这两个关键字,更早的版本要用 JOIN 与 NOT EXISTS 模拟;PostgreSQL 一直支持,Oracle 里的差集写作 MINUS。

基本信息

适用版本MySQL 8.0.31+ 支持;PostgreSQL 各版本都支持
去重行为默认去重,保留重复要写 INTERSECT ALL / EXCEPT ALL
比较口径按整行比较,列个数、顺序与类型必须一致
运算优先级MySQL 中 INTERSECT 高于 UNION 与 EXCEPT,可用括号调整
Oracle 兼容差集写作 MINUS

典型使用场景

  • 求两个用户集合的公共成员
  • 从活跃用户里剔除黑名单
  • 对比测试库与生产库的数据差异
  • 两次统计结果的口径对齐检查
  • 替代多层嵌套的 NOT IN 与 EXISTS

标准写法

标准写法
-- 交集:两张表都有的 id
SELECT id FROM members
INTERSECT
SELECT id FROM paid_users;

-- 差集:members 里有而黑名单里没有的 id
SELECT id FROM members
EXCEPT
SELECT id FROM blacklist;    -- 标准与 PG 写法;Oracle 叫 MINUS

-- 需要保留重复行时
SELECT id FROM members
EXCEPT ALL
SELECT id FROM blacklist;

兼容写法

兼容写法
-- 交集用 INNER JOIN 模拟
SELECT m.id FROM members m
JOIN paid_users p ON p.id = m.id;

-- 差集用 NOT EXISTS 模拟,右表含 NULL 也不会像 NOT IN 那样整段变空
SELECT m.id FROM members m
WHERE NOT EXISTS (SELECT 1 FROM blacklist b WHERE b.id = m.id);

写法与等价替代

写法语义等价替代
INTERSECT两边都有的行,去重INNER JOIN 或 IN 子查询
EXCEPT左边有、右边没有的行,去重NOT EXISTS
INTERSECT ALL两边都有的行,保留重复需计数比较,不易用单条 JOIN 表达
EXCEPT ALL差集且保留重复同上,需要按行计数
MINUSOracle 的差集,语义同 EXCEPT迁移时逐一改写
这两个运算符按整行比较,参与比较的列顺序与类型要严格对齐,否则差异列表会出现大量伪差异;只关心部分列时就显式 SELECT 出那些列,不要在末尾用 SELECT *。
旧版本 MySQL 用 NOT EXISTS 模拟差集比 NOT IN 更稳妥:右表含 NULL 时 NOT IN 的结果可能整段为空,NOT EXISTS 不受影响。
集合运算的先后顺序会改变结果:先取差集再求交集,与先求交集再取差集得到的行并不相同,复杂口径要用括号把运算顺序写清楚。

易错点

  • 旧版本 MySQL 直接执行 INTERSECT 或 EXCEPT:会语法报错,迁移前先确认目标库版本
  • 两侧列顺序或类型不一致:整行比较会把同一条数据判成不同行,差异列表出现大量伪差异
  • 用 NOT IN 模拟差集且右表含 NULL:结果可能整段变空,改用 NOT EXISTS 或直接用 EXCEPT
  • 以为默认保留重复行:INTERSECT/EXCEPT 默认去重,要保留重复必须写 ALL
  • 多条集合运算混写却不加括号:MySQL 中 INTERSECT 优先级更高,实际运算顺序容易与预期不符

数据来源与参考

  • MySQL 8.0 Reference Manual · INTERSECT and EXCEPT
  • PostgreSQL Documentation · Combining Queries
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌