Skip to content

SQLite - UNIONS 子句

UNION 运算符用于将两个或多个 SELECT 语句的结果集合并为一个结果集。它自动从最终结果中移除重复行。

要使 UNION 起作用,必须满足以下条件:

  • UNION 中的每个 SELECT 语句必须具有相同数量的列。
  • 列必须具有相似(兼容)的数据类型。
  • 每个 SELECT 语句中的列也必须按相同的顺序排列。
SELECT column1, column2 FROM table1
[WHERE 条件]
UNION
SELECT column1, column2 FROM table2
[WHERE 条件];

想象一家公司将全职员工和承包商的数据存储在不同的表中。我们想要一个包含所有与公司相关人员的列表。

表 1:employees

ID NAME DEPARTMENT
---------- ---------- ----------
1 Alice Engineering
2 Bob Marketing
3 Charlie Engineering

表 2:contractors

ID NAME PROJECT
---------- ---------- ----------
1 David 'Website Redesign'
2 Charlie 'API Integration'
3 Eve 'Mobile App'

为了获得统一的姓名列表,我们可以使用 UNION。请注意,‘Charlie’ 在两个表中都存在,但 UNION 只会显示他一次。

SELECT name FROM employees
UNION
SELECT name FROM contractors
ORDER BY name;

这将生成以下去重并排序的列表:

name
----------
Alice
Bob
Charlie
David
Eve

UNION ALL 运算符的工作方式与 UNION 相同,但它不会移除重复行。它只是将查询结果集连接起来。

UNION ALL 显著快于 UNION,因为它避免了排序和检查重复项的开销。如果您知道结果集中没有重复项,或者您有意包含它们,请始终选择 UNION ALL 以获得更好的性能。

SELECT column1, column2 FROM table1
[WHERE 条件]
UNION ALL
SELECT column1, column2 FROM table2
[WHERE 条件];

使用相同的 employees 和 contractors 表,UNION ALL 将包含 ‘Charlie’ 两次。

SELECT name FROM employees
UNION ALL
SELECT name FROM contractors;

这将产生以下结果(不使用 ORDER BY 时不保证顺序):

name
----------
Alice
Bob
Charlie
David
Charlie
Eve

您可以在具有不同结构的表上使用 UNION,只要您选择相同数量且类型兼容的列即可。您可以使用字面值(如字符串)来填充缺失的列。

-- 获取所有人员及其角色的列表
SELECT name, 'Employee' AS role, department FROM employees
UNION ALL
SELECT name, 'Contractor' AS role, project FROM contractors
ORDER BY name;

此查询创建一个统一列表,通过创建 role 列来区分两种类型的人员。department 和 project 列合并为一个,这是可以接受的,因为它们都包含文本。

name role department
--------- ---------- -----------------
Alice Employee Engineering
Bob Employee Marketing
Charlie Contractor API Integration
Charlie Employee Engineering
David Contractor Website Redesign
Eve Contractor Mobile App