sql-union-vs-union-all
SQL: UNION 与 UNION ALL
Section titled “SQL: UNION 与 UNION ALL”UNION 运算符的目的
Section titled “UNION 运算符的目的”UNION 和 UNION ALL 是 SQL 中的集合运算符,用于将两个或多个 SELECT 语句的结果集合并为一个单一的结果集。当您在多个表中拥有类似结构的数据并希望将其视为一个整体时,这非常有用。
UNION 的关键要求
Section titled “UNION 的关键要求”要使任何 UNION 操作成功,所涉及的 SELECT 语句必须是“联合兼容的”,这意味着它们必须满足两个严格条件:
- 列数相同: 每个
SELECT语句必须检索相同数量的列。 - 数据类型兼容: 对应列的数据类型必须兼容(例如,您可以将
VARCHAR(50)与VARCHAR(100)联合,或将INT与DECIMAL联合,但不能将DATE与INT联合)。
最终结果集中的列名取自第一个 SELECT 语句。
UNION:合并并去除重复项
Section titled “UNION:合并并去除重复项”UNION 运算符合并结果集,然后执行一个额外的步骤:它扫描合并后的结果并删除任何重复的行。结果是所有查询中仅包含唯一行的集合。
SELECT column1, column2 FROM TableAUNIONSELECT columnA, columnB FROM TableB;假设一家公司将其员工存储在两个表中:FullTimeEmployees(全职员工)和 Contractors(承包商)。两个表都具有相似的结构。
-- 表:FullTimeEmployeesCREATE TABLE FullTimeEmployees (ID INT, Name VARCHAR(50));INSERT INTO FullTimeEmployees VALUES(1, 'Alice'),(2, 'Bob');
-- 表:ContractorsCREATE TABLE Contractors (EmpID INT, FullName VARCHAR(50));INSERT INTO Contractors VALUES(3, 'Charlie'),(1, 'Alice'); -- Alice 也做合同工要获取公司所有人员的唯一列表,我们使用 UNION。请注意,‘Alice’ 的行出现在两个表中。
SELECT ID, Name FROM FullTimeEmployeesUNIONSELECT EmpID, FullName FROM Contractors;UNION 删除了重复的 ‘Alice’ 行。
| ID | Name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
UNION ALL:合并所有行
Section titled “UNION ALL:合并所有行”UNION ALL 运算符更简单、更快。它合并所有查询的结果集,但不执行任何重复项检查。它只是将第二个查询的行附加到第一个查询的行后面。
SELECT column1, column2 FROM TableAUNION ALLSELECT columnA, columnB FROM TableB;使用相同的表,让我们看看 UNION ALL 会做什么。如果我们想计算工作合同的总数(包括重复项),这个查询会很有用。
SELECT ID, Name FROM FullTimeEmployeesUNION ALLSELECT EmpID, FullName FROM Contractors;UNION ALL 包含来自两个表的所有行,包括重复的 ‘Alice’。
| ID | Name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
| 1 | Alice |
性能:关键区别
Section titled “性能:关键区别”在实际应用中,最重要的区别在于性能。UNION ALL 显著快于 UNION。
这是因为 UNION 必须执行额外的工作来查找和消除重复行。这通常涉及对整个合并结果集进行排序或构建所有行的哈希表——这都是资源密集型操作,尤其是在大数据集上。
UNION ALL 不会执行这些操作。它只是简单地连接结果。这是一个轻量得多的操作。
最佳实践: 除非您明确需要删除重复行,否则请始终使用 UNION ALL。如果您知道合并查询的行已经不同,使用 UNION ALL 可以获得免费的性能提升。
总结:何时使用哪个
Section titled “总结:何时使用哪个”| 特征 | UNION | UNION ALL |
|---|---|---|
| 重复行 | 删除重复项 | 保留所有重复项 |
| 性能 | 较慢(由于排序/哈希) | 较快(简单连接) |
| 用例 | 从多个来源获取唯一项列表。 | 合并来自多个来源的所有记录,特别是用于 COUNT 等聚合操作或当您知道不可能有重复项时。 |