SQL - UNION 运算符



SQL UNION 运算符

SQL UNION 运算符用于组合来自多个表的数据,同时消除重复行(如有)。

要在多个表上使用 UNION 运算符,所有这些表都必须是联合兼容的。当且仅当它们满足以下条件时,才被称为联合兼容:

  • 选择具有相同数据类型的相同列数。
  • 这些列的顺序也必须相同。
  • 它们不需要具有相同的行数。

满足这些条件后,UNION 运算符将来自多个表的行作为结果表返回,该结果表不包含这些表中的所有重复值。

最终结果集中的列名将基于第一个 SELECT 语句中选择的列名。如果要在最终结果集中为列使用不同的名称,可以在 SELECT 语句中使用别名。

语法

UNION 运算符的基本语法如下:

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
UNION
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition];

此处,给定条件可以是基于您需求的任何给定表达式。

单个字段上的 UNION

如果要使用 UNION 组合单个字段上两个或多个 SELECT 语句的结果集,可以简单地在每个查询的 SELECT 语句中包含该字段。UNION 运算符将自动删除最终结果集中的任何重复值。

在单个字段上使用 UNION 时,结果集中的列名将由第一个 SELECT 语句中的列名确定。因此,可能需要在 SELECT 语句中使用别名,以确保列名对最终结果集有意义。

示例

假设我们使用 CREATE TABLE 语句在 MySQL 数据库中创建了一个名为 CUSTOMERS 的表,如下所示:

CREATE TABLE CUSTOMERS (
   ID INT NOT NULL,
   NAME VARCHAR (20) NOT NULL,
   AGE INT NOT NULL,
   ADDRESS CHAR (25),
   SALARY DECIMAL (18, 2),       
   PRIMARY KEY (ID)
);

以下查询使用 INSERT 语句将值插入此表:

INSERT INTO CUSTOMERS VALUES
(1, 'Ramesh', 32, 'Ahmedabad', 2000.00),
(2, 'Khilan', 25, 'Delhi', 1500.00),
(3, 'Kaushik', 23, 'Kota', 2000.00),
(4, 'Chaitali', 25, 'Mumbai', 6500.00),
(5, 'Hardik', 27, 'Bhopal', 8500.00),
(6, 'Komal', 22, 'Hyderabad', 4500.00),
(7, 'Muffy', 24, 'Indore', 10000.00);

CUSTOMERS 表如下所示:

ID 姓名 年龄 地址 薪水
1 Ramesh 32 Ahmedabad 2000.00
2 Khilan 25 Delhi 1500.00
3 Kaushik 23 Kota 2000.00
4 Chaitali 25 Mumbai 6500.00
5 Hardik 27 Bhopal 8500.00
6 Komal 22 Hyderabad 4500.00
7 Muffy 24 Indore 10000.00

现在,使用 CREATE TABLE 语句创建第二个表 ORDERS,如下所示:

CREATE TABLE ORDERS (
   OID INT NOT NULL,
   DATE DATETIME NOT NULL,
   CUSTOMER_ID INT NOT NULL,
   AMOUNT INT NOT NULL,      
   PRIMARY KEY (OID)
);

以下查询使用 INSERT 语句将值插入此表:

INSERT INTO ORDERS VALUES
(102, '2009-10-08 00:00:00', 3, 3000),
(100, '2009-10-08 00:00:00', 3, 1500),
(101, '2009-11-20 00:00:00', 2, 1560),
(103, '2008-05-20 00:00:00', 4, 2060);

ORDERS 表如下所示:

OID 日期 客户ID 金额
102 2009-10-08 00:00:00 3 3000.00
100 2009-10-08 00:00:00 3 1500.00
101 2009-11-20 00:00:00 2 1560.00
103 2008-05-20 00:00:00 4 2060.00

使用以下查询,让我们组合来自 CUSTOMERS 和 ORDERS 表的 SALARY 和 AMOUNT 列(因为这些列具有相似的数据类型):

SELECT SALARY FROM CUSTOMERS UNION SELECT AMOUNT FROM ORDERS;

输出

以上查询的输出如下:

薪水
2000.00
1500.00
6500.00
8500.00
4500.00
10000.00
3000.00
1560.00
2060.00

多个字段上的 UNION

当我们在多个字段上使用 UNION 时,每个 SELECT 语句中的字段数量和顺序必须匹配。此外,每个 SELECT 语句中字段的数据类型必须兼容才能使 UNION 正确工作。如果数据类型不兼容,则可能需要使用转换函数(如 CAST 或 CONVERT)来确保数据类型匹配。

示例

由于 CUSTOMERS 和 ORDERS 表本身并不兼容联合,让我们首先使用左连接和右连接将这两个表连接到一个更大的表中。检索到的连接表将具有相同数量的列和相同的数据类型,从而成为联合兼容的。现在,这些表使用以下所示的 UNION 查询组合:

SELECT  ID, NAME, AMOUNT, DATE FROM CUSTOMERS
LEFT JOIN ORDERS ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION
SELECT  ID, NAME, AMOUNT, DATE FROM CUSTOMERS
RIGHT JOIN ORDERS ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

输出

这将产生以下结果:

ID 姓名 金额 日期
1 Ramesh NULL NULL
2 Khilan 1560 2009-11-20 00:00:00
3 Kaushik 3000 2009-10-08 00:00:00
3 Kaushik 1500 2009-10-08 00:00:00
4 Chaitali 2060 2008-05-20 00:00:00
5 Hardik NULL NULL
6 Komal NULL NULL
7 Muffy NULL NULL

带有 WHERE 子句的 UNION

我们可以将 WHERE 子句与 UNION 运算符一起使用,以在组合之前筛选每个 SELECT 语句的结果。

语法

以下是将 WHERE 子句与 UNION 运算符一起使用的语法:

SELECT column1, column2, column3
FROM table1
WHERE column1 = 'value1'
UNION
SELECT column1, column2, column3
FROM table2
WHERE column1 = 'value2';

示例

在以下查询中,我们分别从“CUSTOMERS”和“ORDERS”表中检索 ID 大于 5 和 2 的客户的 ID:

SELECT ID, SALARY FROM CUSTOMERS WHERE ID > 5
UNION
SELECT CUSTOMER_ID, AMOUNT FROM ORDERS WHERE CUSTOMER_ID > 2;

输出

以下是产生的结果:

ID 薪水
6 4500.00
7 10000.00
3 3000.00
3 1500.00
4 2060.00

带有 ORDER BY 子句的 UNION

当我们将 ORDER BY 子句与 UNION 一起使用时,它会组合所有 SELECT 语句的排序结果集,并产生单个排序结果集。

示例

在这里,我们分别从“CUSTOMERS”和“ORDERS”表中检索 ID 大于 5 和 2 的客户的 ID,按其薪水从低到高排序:

SELECT ID, SALARY FROM CUSTOMERS WHERE ID > 5
UNION
SELECT CUSTOMER_ID, AMOUNT FROM ORDERS WHERE CUSTOMER_ID > 2
ORDER BY SALARY;

输出

以下是以上查询的输出:

ID 薪水
3 1500.00
4 2060.00
3 3000.00
6 4500.00
7 10000.00
UNION 语句中的 ORDER BY 子句适用于整个结果集,而不仅仅是最后一个 SELECT 语句。

带有别名的 UNION

我们可以在 UNION 运算符的 SELECT 语句中使用别名来为表或列赋予临时名称,这在处理具有相似名称的多个表或列时非常有用。

使用带有别名的 UNION 时,需要注意的是,列别名由第一个 SELECT 语句确定。因此,如果要在不同的 SELECT 语句中为同一列使用不同的别名,则需要在所有 SELECT 语句中使用列别名,以确保最终结果集中列名的前后一致性。

语法

以下是使用带有别名的 Union 的语法:

SELECT column1 AS alias1, column2 AS alias2
FROM table1
UNION
SELECT column3 AS alias1, column4 AS alias2
FROM table2;

示例

以下查询检索两个表中的所有 ID,以及每个 ID 是客户还是他们所下订单的指示:

SELECT ID, 'customer' AS type FROM CUSTOMERS
UNION
SELECT OID, 'order' AS type FROM ORDERS;

输出

以下是产生的输出:

ID 类型
1 客户
2 客户
3 客户
4 客户
5 客户
6 客户
7 客户
100 订单
101 订单
102 订单
103 订单

还有其他两个运算符类似于 UNION 运算符。

  • SQL INTERSECT 运算符 - 它用于组合两个 SELECT 语句,但仅返回第一个 SELECT 语句中与第二个 SELECT 语句中的行相同的行。

  • SQL EXCEPT 运算符 - 它组合两个 SELECT 语句,并返回第一个 SELECT 语句中第二个 SELECT 语句未返回的行。

广告