在处理数据库查询时,我们经常会遇到需要合并多个查询结果、寻找共同项或排除特定记录的场景。在 SQL 中,每一个 SELECT 语句产生的结果都可以看作是一个记录的集合 ,本文将带你了解集合的三大基础操作:并集 (Union) 、交集 (Intersect) 和 差集 (Except)。
文章目录
- [一、 并集(UNION)](#一、 并集(UNION))
-
- [1.1 UNION 与 UNION ALL](#1.1 UNION 与 UNION ALL)
- [二、 交集 (INTERSECT)](#二、 交集 (INTERSECT))
- [三、 差集 (EXCEPT):](#三、 差集 (EXCEPT):)
- [四、 其他建议](#四、 其他建议)
一、 并集(UNION)
并集操作用于将两个或多个查询的结果组合成一个单一的结果集。
1.1 UNION 与 UNION ALL
合并是最常用的集合操作。
- UNION :合并结果并自动去重,它会进行一次去重判断,因此会有额外的计算开销。
- UNION ALL :简单合并所有结果,保留重复项,由于不需要排序去重,性能更高。
案例: 获取所有"高级工程师 (Senior Engineer)"和"经理 (Manager)"的员工编号:
sql
SELECT emp_no FROM titles WHERE title = 'Senior Engineer'
UNION
SELECT emp_no FROM dept_manager;

在单表查询中,
WHERE title = 'A' OR title = 'B'的逻辑本质上就是并集。但在跨表(如员工表与经理表)合并数据时,UNION是不二之选。
注意事项
- 列数一致 :所有
SELECT的字段数量必须相同。 - 类型兼容:对应列的数据类型必须可以相互转换。
- 排序规则 :如果要排序,
ORDER BY必须放在最后一个查询之后。
二、 交集 (INTERSECT)
交集用于返回同时存在于多个结果集中的记录。
案例: 找出那些既拥有"高级工程师 (Senior Engineer)"头衔,又曾担任过"经理 (Manager)"的骨干员工:
sql
SELECT emp_no FROM titles WHERE title = 'Senior Engineer'
INTERSECT
SELECT emp_no FROM dept_manager;

在单表查询中,多个
WHERE条件的AND逻辑等同于交集,跨表查询时需要用INTERSECT。
三、 差集 (EXCEPT):
差集用于从第一个结果集中去掉存在于第二个结果集中的记录。
案例:找出所有从未担任过经理(Manager)的普通高级工程师(Senior Engineer):
sql
SELECT emp_no FROM titles WHERE title = 'Senior Engineer'
EXCEPT
SELECT emp_no FROM dept_manager;

四、 其他建议
- 优先使用 UNION ALL :除非业务逻辑明确要求结果唯一,否则优先使用
UNION ALL以规避去重带来的性能损耗。 - 字段别名 :最终结果集的列名由第一个
SELECT语句决定,建议在第一句中明确定义AS别名。