在数据库操作中,经常需要从不同的表中获取数据并将其合并为一个结果集。SQL提供了一种非常有用的机制来实现这一点,那就是 UNION 和 UNION ALL 操作。本文将详细介绍这些操作的用法和区别。
UNION 操作用于将两个或多个 SELECT 语句的结果合并为一个结果集。与 JOIN 不同,UNION 不是将不同表的列合并,而是将不同表的行合并。合并后的结果会去除重复的行。以下是 UNION 操作的基本语法:
SELECT columnlist FROM table1
UNION
SELECT columnlist FROM table2
要使用 UNION 合并两个表,需要满足以下要求:
例如,如果想要列出所有产品类别和子类别,可以使用 UNION 操作来实现:
SELECT C.Name FROM Production.ProductCategory AS C
UNION ALL
SELECT S.Name FROM Production.ProductSubcategory AS S
这样,就得到了一个合并的名称列表。但是,如果想要区分哪些是类别名称,哪些是子类别名称,可以添加一个新列来指示类别类型:
SELECT 'category', C.Name FROM Production.ProductCategory AS C
UNION ALL
SELECT 'subcategory', S.Name FROM Production.ProductSubcategory AS S
UNION 和 UNION ALL 的主要区别在于 UNION 返回的是合并结果中的唯一行,而 UNION ALL 返回的是所有行,包括重复的行。例如:
SELECT person.Address.City FROM person.Address
这个查询返回了 19614 行。如果使用 UNION 操作:
SELECT person.Address.City FROM person.Address
UNION
SELECT person.Address.City FROM person.Address
这个查询返回了 575 行,这是表中唯一的城市名称的数量。如果使用 UNION ALL:
SELECT person.Address.City FROM person.Address
UNION ALL
SELECT person.Address.City FROM person.Address
这个查询返回了 39228 行,即城市名称的完整集合的两倍。
假设管理层想要一个合并的人员、供应商和商店名称的列表,可以通过创建三个单独的查询,然后使用 UNION 操作将它们组合起来。然后可以对列表进行排序:
SELECT 'Person' AS Source, FirstName + ' ' + LastName AS Name FROM person.Person
UNION
SELECT 'Vendor', Name FROM Purchasing.Vendor
UNION
SELECT 'Store', Name FROM Sales.Store
ORDER BY Name;
乍一看,可能认为 ORDER BY 子句只适用于最后一个 SELECT 语句,但实际上它适用于 UNION 返回的所有结果。数据库引擎首先处理所有的 UNION 语句,然后是 ORDER BY。
如果对处理顺序有疑问,可以使用括号 “()” 来控制求值顺序,就像可以在表达式中做的那样。以下是带有括号的一般语句:
(
SELECT 'Person' AS Source, FirstName + ' ' + LastName AS Name FROM person.Person
UNION
SELECT 'Vendor', Name FROM Purchasing.Vendor
UNION
SELECT 'Store', Name FROM Sales.Store
)
ORDER BY Name;