SQL中的UNION运算符
如果可以说一个基本的结构化查询语言(SQL)操作符没有得到充分利用,那么UNION可能符合这个描述。它的功能通常很容易被一个结构良好的查询复制——导致许多数据库管理员和程序员认为UNION有点草率。但是,如果使用它可以避免运行过于复杂的查询(或多个查询),那么使用它可能会更清楚。在某些情况下,它甚至可以提供更好的性能。
此示例提供了在SQL中提供联盟运算符的简短概述。因此,您希望了解关系数据库和SQL编程的基础知识 - 包括如何创建合适的数据库进行测试。作为开源包,MySQL通常用于学习数据库设计服务器软件。对于台式机上的数据库,学习Microsoft Access.将提供合适的环境和背景知识,用于练习工会运营商的使用。
基本的联盟
在其最简单的级别,Union运算符将两个数据库查询加入单个结果。这些查询可以参考不同的列和表,从而满足以下条件:
- 两个查询必须返回相同数量的列。
- 对于结果中的每个列,两个查询都必须返回“兼容”的数据类型。
给定如下所示的表结构,下面的代码显示了一个简单的UNION操作,它的行为类似于WHERE子句中的OR,在满足任意一组条件时选择行。
SELECT [id], [name], [country] FROM Suppliers WHERE country = 'Japan'
要从两个不同的表中选择和统一结果,您可以简单地引用第二个查询中的其他表:
SELECT [id], [name], [country] FROM Customers WHERE country = '英国' WHERE country = '英国'
你没有理由不能统一两个以上查询的结果,只需重复使用UNION:
SELECT [id], [name], [country] FROM inspectionwhere country = '英国' WHERE country = '英国'
在列名在结构之间不同的情况下,结果数据集通常将使用第一个查询的列名。
SQL数据库合并结果,以便UNION中匹配两个查询的行只在结果集中出现一次。您应该注意,在不同的表中出现相同的行,不算作重复。
在大多数情况下,UNION的标准行动是必需的。对于需要重复行的情况,可以使用UNION ALL操作符。
UNION ALL
Union ally of Union仅在返回两个查询的所有行中,即使这导致重复。如果您知道不可能重复记录,则使用Union所有可以提供稍微更好的性能,因为大多数数据库系统将避免在使用联盟时筛选重复的记录。
在下面的示例中,如果“Test Corp.”的记录的国家是“United Kingdom”,那么它现在将在结果集中出现两次。
SELECT [id], [name], [country] FROM Suppliers WHERE country = 'United Kingdom' UNION ALL SELECT [id], [name], [country] FROM Suppliers WHERE name = 'Test Corp.'
如果将三个或更多查询与Union和Union所有操作的混合组合,则应使用括号来确保查询在您打算的方式中组合,而不是数据库系统决定执行此操作的方式。请记住,联盟是一种组合二因此,当使用多个union时,您需要控制配对。
排序结果
订购union组合的多个查询的结果并不总是一个直接的过程。这两个查询返回相同列名的情况,可以通过将订单逐个子句添加到最后一个查询来订购组合结果集。
SELECT [id], [name], [country], [phone] FROM Customers ORDER BY [telephone]
在列名为不同的情况下,使用第一个查询的列名。因此,您可以使用这些列名或使用列的编号而不是其名称来创建订单逐个子句。以下SQL查询对上面的一个相同的操作执行:
来自供应商联盟的[ID],[姓名],[国家],[电话]从客户订单中选择[ID],[姓名],[国家],[手机]
使用括号和每个查询的子句使用括号和单独的订单允许您独立地对另一个进行排序。第二个查询的有序结果仅将第一个附加到第一个,而不是在订购中混合。
(从供应商按[name])Union(选择[ID],[Name],[Country]从客户订单)(选择[id],[name],[国家])
为UNION操作重命名列
虽然不是严格要求两个查询的列具有相同的名称,但在构造ORDER BY子句时它肯定是有用的。可以使用SQL操作符AS重命名列。如下面的例子所示:
SELECT [id], [name], [telephone] FROM Suppliers ORDER BY telephone . SELECT [id], [name], [telephone] FROM Suppliers
如果没有重命名客户表的手机列,Order by子句会导致错误,因为电话不是第一个查询中列的名称。
铸造和转换柱的联合操作
请记住,使用UNION之前规定的第二个要求要求每个查询的列是“兼容的” - 这意味着数据库系统可以自动将数据转换为第二查询结果中的数据以匹配第一个查询中使用的数据类型。
如果希望以一种不兼容的数据类型组合不同的数据结构,则可以使用CAST和CONVERT函数。这可能是一个冗长的主题,在这里不能全面讨论。然而,作为介绍……
CAST和CONVERT是两个用于将一种数据类型转换为另一种数据类型的函数。一般来说,数据库系统采用了更标准的CAST,而Microsoft SQL Server使用了CONVERT函数。如果您完全不熟悉这个非常流行的软件,可以学习它你需要知道的SQL Server在很短的时间内。
下面的示例从一个不同数据类型的表中选择多个列。这些结果与使用UNION运算符的第二个查询组合在一起。尽管“CRM_No”是供应商表中的一个数字和客户表中的一个文本值,但是这个示例是有效的,因为数据库通常可以自动将数字转换为文本值。
SELECT [id], [name], [CRM_No] FROM Suppliers ORDER BY [CRM_No]
但是,当查询的顺序颠倒时,将生成一个错误,因为数据库不能自动将文本值转换为数字。
从供应商联盟中选择[ID],[名称],[CRM_NO]从客户订购的[CRM_NO]选择[ID],[名称],[CRM_NO]
要解决此问题,您可以使用特定的CAST操作来强制供应商表中的“CRM_NO”将被视为文本(最大长度为30):
SELECT [id], [name], [CRM_No] FROM Customers ORDER BY [CRM_No] FROM Customers ORDER BY [CRM_No]
下面是同样的例子,这次使用的是SQL Server的CONVERT:
SELECT [id], [name], CONVERT(VARCHAR(30), [CRM_No]) FROM供应商
联盟
SELECT [id], [name], [CRM_No] FROM Customers
ORDER BY (CRM_No)
请注意,CAST和CONVERT函数对Microsoft Access用户不可用。Access有自己独特的一组转换例程,在这种情况下将使用CSTR([CRM_No])。
进一步阅读
UNION只是加入疑问和来自不同表的结果中的许多方法中的一种。应该探索的其他类似的SQL运算符是相交的和减号。详细描述了许多这些基本技术从初学者到中间的实用SQL技能。