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语句在SQL数据库中创建了一个名为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);
insert INTO CUSTOMERS VALUES(2, 'Khilan', 25, 'Delhi', 1500.00);
insert INTO CUSTOMERS VALUES(3, 'kaushik', 23, 'Kota', 2000.00);
insert INTO CUSTOMERS VALUES(4, 'Chaitali', 25, 'Mumbai', 6500.00);
insert INTO CUSTOMERS VALUES(5, 'Hardik', 27, 'Bhopal', 8500.00);
insert INTO CUSTOMERS VALUES(6, 'Komal', 22, 'MP', 4500.00);
insert INTO CUSTOMERS VALUES(7, 'Muffy', 24, 'Indore', 10000.00);
如果我们使用SELECT语句验证CUSTOMERS表的内容,我们可以观察到插入的记录如下所示:
表1 - CUSTOMERS表如下所示。
SELECT * from CUSTOMERS;
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 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 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+-----------+----------+
现在,根据以下的CREATE TABLE语句创建第二个表ORDERS
CREATE TABLE ORDERS (
OID INT NOT NULL,
DATES 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);
insert INTO ORDERS VALUES(100, '2009-10-08 00:00:00', 3, 1500);
insert INTO ORDERS VALUES(101, '2009-11-20 00:00:00', 2, 1560);
insert INTO ORDERS VALUES(103, '2008-05-20 00:00:00', 4, 2060);
如果我们使用SELECT语句验证ORDERS表的内容,我们可以观察到如下插入的记录−
表2 − ORDERS表如下所示。
SELECT * from ORDERS;
+-----+---------------------+-------------+--------+
|OID | DATES | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+-----+---------------------+-------------+--------+
使用以下查询,让我们尝试将 CUSTOMERS 表中的 SALARY 列和 ORDERS 表中的 AMOUNT 列进行合并,因为这些列具有相似的数据类型。
SELECT SALARY
FROM CUSTOMERS
UNION
SELECT AMOUNT
FROM ORDERS
输出
上述查询的输出如下:
+----------+
| SALARY |
+----------+
| 2000.00 |
| 1500.00 |
| 6500.00 |
| 8500.00 |
| 4500.00 |
| 10000.00 |
| 1560.00 |
| 3000.00 |
| 2060.00 |
+----------+
多个字段上的UNION操作
当我们在多个字段上使用UNION操作时,每个SELECT语句中字段的数量和顺序必须匹配。此外,每个SELECT语句中字段的数据类型必须兼容,以确保UNION操作能够正确运行。如果数据类型不兼容,您可能需要使用转换函数,如CAST或CONVERT,以确保数据类型匹配。
示例
由于CUSTOMERS和ORDERS表在个别情况下不具备联合兼容性,让我们首先使用左连接和右连接将这两个表连接成一个更大的表。连接后的表具有相同数量和相同数据类型的列,从而具备了联合兼容性。现在,使用下面所示的UNION查询组合这些表 –
SELECT ID, NAME, AMOUNT, DATES
FROM CUSTOMERS
LEFT JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION
SELECT ID, NAME, AMOUNT, DATES
FROM CUSTOMERS
RIGHT JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
输出
这将产生以下结果 –
+------+----------+--------+---------------------+
| ID | NAME | AMOUNT | DATES |
+------+----------+--------+---------------------+
| 1 | Ramesh | NULL | NULL |
| 2 | Khilan | 1560 | 2009-11-20 00:00:00 |
| 3 | kaushik | 1500 | 2009-10-08 00:00:00 |
| 3 | kaushik | 3000 | 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 |
+------+----------+--------+---------------------+
UNION带WHERE子句
我们可以使用带WHERE子句的UNION运算符,在组合之前过滤每个SELECT语句的结果。
语法
使用带WHERE子句的UNION运算符的语法如下:
SELECT column1, column2, column3
FROM table1
WHERE column1 = 'value1'
UNION
SELECT column1, column2, column3
FROM table2
WHERE column1 = 'value2';
示例
在以下查询中,我们试图检索’CUTOMERS’和’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 | SALARY |
+----+----------+
| 3 | 1500.00 |
| 3 | 3000.00 |
| 4 | 2060.00 |
| 6 | 4500.00 |
| 7 | 10000.00 |
+----+----------+
UNION with ORDER BY clause
当我们在使用UNION和ORDER BY子句时,它会将所有SELECT语句的排序结果集合并,并产生一个排序的结果集。
示例
在这个例子中,我们试图从’CUTOMERS’表和’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 | SALARY |
+----+----------+
| 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 | type |
+-----+----------+
| 1 | customer |
| 2 | customer |
| 3 | customer |
| 4 | customer |
| 5 | customer |
| 6 | customer |
| 7 | customer |
| 100 | order |
| 101 | order |
| 102 | order |
| 103 | order |
+-----+----------+
有另外两个类似于UNION操作符的操作符。
-
SQL INTERSECT Operator - 用于结合两个SELECT语句,只返回第一个SELECT语句与第二个SELECT语句中相同的行。
-
SQL EXCEPT Operator - 结合两个SELECT语句,并返回第一个SELECT语句中不被第二个SELECT语句返回的行。