MySQL - UNION 运算符
MySQL UNION 运算符
MySQL 中的 UNION 运算符可将来自多个表。
如果我们想从多个表中逐行选择行,或者从单个表中选择多组行并将其合并为一个结果集,则可以使用 UNION。
要在多个表上使用 UNION 运算符,所有这些表都必须兼容联合。当且仅当它们满足以下条件时,才称它们兼容联合:
- 选择的列数相同且数据类型相同。
- 这些列的顺序也必须相同。
- 它们的行数不必相同。
满足这些条件后,UNION 运算符将返回来自多个表的行,并将其合并为一个结果表,该结果表不包含这些表中的所有重复值。
UNION 从 MySQL 4.0 开始可用。本节演示如何使用它。
语法
MySQL 中 UNION 运算符的基本语法如下 -
SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2;
示例
首先,我们使用以下 CREATE TABLE 查询创建名为 PROSPECT 的潜在客户表 -
CREATE TABLE PROSPECT ( FNAME CHAR(20) NOT NULL, LNAME CHAR(20), ADDRESS VARCHAR(100) NOT NULL );
现在,我们使用下面的 INSERT 语句将记录插入此表 -
INSERT INTO PROSPECT VALUES ('Peter', 'Jones', '482 Rush St., Apt. 402'), ('Bernice', 'Smith', '916 Maple Dr.');
PROSPECT 表创建如下 -
FNAME | LNAME | ADDRESS |
---|---|---|
Peter | Jones | 482 Rush St., Apt. 402 |
Bernice | Smith | 916 Maple Dr. |
ACTIVE 表 −
然后,我们使用以下 CREATE TABLE 查询创建一个名为 ACTIVE 的活跃客户表 −
CREATE TABLE ACTIVE ( FNAME CHAR(20) NOT NULL, LNAME CHAR(20), ADDRESS VARCHAR(100) NOT NULL );
使用以下 INSERT 语句将记录插入 ACTIVE 表 -
INSERT INTO ACTIVE VALUES ('Grace', 'Peterson', '16055 Seminole Ave.'), ('Bernice', 'Smith', '916 Maple Dr.'), ('Walter', 'Brown', '8602 1st St.');
ACTIVE 表创建如下 -
FNAME | LNAME | ADDRESS |
---|---|---|
Grace | Peterson | 16055 Seminole Ave. |
Bernice | Smith | 916 Maple Dr. |
Walter | Brown | 8602 1st St. |
现在,您想通过合并所有表中的姓名和地址来创建一个邮件列表。UNION 提供了一种实现此目的的方法。
以下查询演示了如何一次性从所有表中选择姓名和地址 -
SELECT FNAME, LNAME, ADDRESS FROM PROSPECT UNION SELECT FNAME, LNAME, ADDRESS FROM ACTIVE;
输出
获得以下输出 -
FNAME | LNAME | ADDRESS |
---|---|---|
Peter | Jones | 482 Rush St., Apt. 402 |
Bernice | Smith | 916 Maple Dr. |
Grace | Peterson | 16055 Seminole Ave. |
Walter | Brown | 8602 1st St. |
如您所见,结果集中避免了重复。
带有 WHERE 子句的 UNION
我们可以使用带有 UNION 运算符的 WHERE 子句在合并每个 SELECT 语句的结果之前对其进行筛选。
语法
以下是使用带有 UNION 运算符的 WHERE 子句的语法 -
SELECT column1, column2, column3 FROM table1 WHERE column1 = 'value1' UNION SELECT column1, column2, column3 FROM table2 WHERE column1 = 'value2';
示例
我们使用上例中的相同表,使用带有 WHERE 子句的 UNION 运算符检索合并的记录 -
SELECT FNAME, LNAME, ADDRESS FROM PROSPECT WHERE LNAME = 'Jones' UNION SELECT FNAME, LNAME, ADDRESS FROM ACTIVE WHERE LNAME = 'Peterson';
输出
获得以下输出 -
FNAME | LNAME | ADDRESS |
---|---|---|
Peter | Jones | 482 Rush St., Apt. 402 |
Grace | Peterson | 16055 Seminole Ave. |
UNION 与 ORDER BY 子句结合使用
当我们使用 UNION 与 ORDER BY 子句时,它会合并所有 SELECT 语句的排序结果集,并生成单个排序结果集。
语法
以下是使用 UNION 运算符和 ORDER BY 子句的基本语法 -
SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2 ORDER BY column_name;
示例
尝试使用以下查询,根据结果集"lname"列中的值,按升序对表记录进行排序 -
SELECT FNAME, LNAME, ADDRESS FROM PROSPECT UNION SELECT FNAME, LNAME, ADDRESS FROM ACTIVE ORDER BY LNAME;
输出
获得以下输出 -
FNAME | LNAME | ADDRESS |
---|---|---|
Walter | Brown | 8602 1st St. |
Peter | Jones | 482 Rush St., Apt. 402 |
Grace | Peterson | 16055 Seminole Ave. |
Bernice | Smith | 916 Maple Dr. |
带别名的 UNION
我们可以在 MySQL 的 UNION 语句中使用别名,为表或列指定一个临时名称,这在处理多个名称相似的表或列时非常有用。
在使用带别名的 UNION 时,需要注意的是,列别名由第一个 SELECT 语句决定。因此,如果您想在不同的 SELECT 语句中为同一列使用不同的别名,则需要在所有 SELECT 语句中使用列别名,以确保最终结果集中的列名一致。
语法
以下是使用 Union 和别名的语法 -
SELECT column1 AS alias1, column2 AS alias2 FROM table1 UNION SELECT column3 AS alias1, column4 AS alias2 FROM table2;
示例
在下面的示例中,我们尝试使用别名来合并两个表,以表示结果集中的字段 -
SELECT FNAME AS Firstname, LNAME AS Lastname, ADDRESS AS Address FROM PROSPECT UNION SELECT FNAME, LNAME, ADDRESS FROM ACTIVE;
输出
获得以下输出 -
Firstname | Lastname | Address |
---|---|---|
Peter | Jones | 482 Rush St., Apt. 402 |
Bernice | Smith | 916 Maple Dr. |
Grace | Peterson | 16055 Seminole Ave. |
Walter | Brown | 8602 1st St. |
UNION ALL 运算符
如果要选择所有记录(包括重复项),请在第一个 UNION 关键字后跟 ALL -
SELECT fname, lname, ADDRESS FROM prospect UNION ALL SELECT fname, lname, ADDRESS FROM active;
输出
获得以下输出 -
FNAME | LNAME | ADDRESS |
---|---|---|
Peter | Jones | 482 Rush St., Apt. 402 |
Bernice | Smith | 916 Maple Dr. |
Grace | Peterson | 16055 Seminole Ave. |
Bernice | Smith | 916 Maple Dr. |
Walter | Brown | 8602 1st St. |
使用客户端程序的联合运算符
除了直接在 MySQL 服务器中对 MySQL 表应用联合运算符外,我们还可以使用客户端程序对 MySQL 表应用联合操作。
语法
以下是不同编程语言中 MySQL 表中联合运算符的语法 -
要在 PHP 程序中使用 UNION 运算符合并表,我们需要使用 mysqli 函数 query() 执行包含 UNION 运算符的 SQL 语句,如下所示 -
$sql = "SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2"; $mysqli->query($sql);
要在 PHP 程序中使用 UNION 运算符合并表,我们需要使用 mysql2 函数 query() 执行包含 UNION 运算符的 SQL 语句,如下所示 -
sql= " SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2"; con.query(sql);
要通过 PHP 程序使用 UNION 运算符合并表,我们需要使用名为 executeQuery() 的 JDBC type 4 驱动函数执行包含 UNION 运算符的 SQL 语句,如下所示 -
String sql = "SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2"; statement.executeQuery(sql);
要通过 PHP 程序使用 UNION 运算符合并表,我们需要使用 MySQL Connector/Python 函数 execute() 执行包含 UNION 运算符的 SQL 语句,如下所示 -
union_query = "SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2" cursorObj.execute(union_query);
示例
以下是此操作在各种编程语言中的实现 -
$dbhost = 'localhost'; $dbuser = 'root'; $dbpass = 'password'; $dbname = 'TUTORIALS'; $mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname); if($mysqli->connect_errno ) { printf("Connect failed: %s
", $mysqli->connect_error); exit(); } //printf('Connected successfully.
'); $sql = "SELECT fname, lname, addr FROM prospect UNION SELECT first_name, last_name, address FROM customer UNION SELECT company, '', street FROM vendor;"; $result = $mysqli->query($sql); if ($result->num_rows > 0) { printf("Table records: "); while($row = $result->fetch_assoc()) { printf("First Name %s, Last Name: %s, Address %s", $row["fname"], $row["lname"], $row["addr"],); printf(" "); } } else { printf('No record found.
'); } mysqli_free_result($result); $mysqli->close();
输出
获得的输出如下 -
Table records: First Name Peter, Last Name: Jones, Address 482 Rush St., Apt. 402 First Name Bernice, Last Name: Smith, Address 916 Maple Dr. First Name Grace, Last Name: Peterson, Address 16055 Seminole Ave. First Name Walter, Last Name: Brown, Address 8602 1st St. First Name ReddyParts, Inc., Last Name: , Address 38 Industrial Blvd. First Name Parts-to-go, Ltd., Last Name: , Address 213B Commerce Park.
var mysql = require('mysql2'); var con = mysql.createConnection({ host: "localhost", user: "root", password: "Nr5a0204@123" }); //连接到 MySQL con.connect(function (err) { if (err) throw err; console.log("Connected!"); console.log("--------------------------"); //创建数据库 sql = "create database TUTORIALS" con.query(sql); //选择数据库 sql = "USE TUTORIALS" con.query(sql); //创建 PROSPECT 表 sql = "CREATE TABLE PROSPECT( fname varchar(400), lname varchar(400), addr varchar(200));" con.query(sql); //插入记录 sql = "INSERT INTO PROSPECT (fname, lname, addr) VALUES ('peter', 'Jones', '482 Rush St., Apt. 402'), ('Bernice', 'Smith', '916 Maple Dr.');" con.query(sql); //创建 CUSTOMER 表 sql = "CREATE TABLE CUSTOMER( last_name varchar(400), first_name varchar(400), address varchar(200));" con.query(sql); //插入记录 sql = "INSERT INTO CUSTOMER (last_name, first_name, address) VALUES ('Peterson', 'Grace', '16055 Seminole Ave.'), ('Smith', 'Bernice', '916 Maple Dr.'), ('Brown', 'Walter', '8602 1st St.');" con.query(sql); //创建 vendor 表 sql = "CREATE TABLE vendor( company varchar(400), street varchar(400));" con.query(sql); //插入记录 sql = "INSERT INTO vendor (company, street) VALUES ('ReddyParts, Inc.', '38 Industrial Blvd.'), ('Parts-to-go, Ltd.', '213B Commerce Park.');" con.query(sql); //使用 UNION sql = "SELECT fname, lname, addr FROM prospect UNION SELECT first_name, last_name, address FROM customer UNION SELECT company, '', street FROM vendor;" con.query(sql, function(err, result){ if (err) throw err console.log(result) }); });
输出
生成的输出如下 -
Connected! -------------------------- [ { fname: 'peter', lname: 'Jones', addr: '482 Rush St., Apt. 402' }, { fname: 'Bernice', lname: 'Smith', addr: '916 Maple Dr.' }, { fname: 'Grace', lname: 'Peterson', addr: '16055 Seminole Ave.' }, { fname: 'Walter', lname: 'Brown', addr: '8602 1st St.' }, { fname: 'ReddyParts, Inc.', lname: '', addr: '38 Industrial Blvd.' }, { fname: 'Parts-to-go, Ltd.', lname: '', addr: '213B Commerce Park.' } ]
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class UnionOperator { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/TUTORIALS"; String user = "root"; String password = "password"; ResultSet rs; try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection con = DriverManager.getConnection(url, user, password); Statement st = con.createStatement(); //System.out.println("Database connected successfully...!"); String sql = "SELECT fname, lname, addr FROM prospect UNION SELECT first_name, last_name, address FROM customer UNION SELECT company, '', street FROM vendor"; rs = st.executeQuery(sql); System.out.println("Table records: "); while(rs.next()) { String fname = rs.getString("fname"); String lname = rs.getString("lname"); String addr = rs.getString("addr"); System.out.println("First Name: " + fname + ", Last Name: " + lname + ", Address: " + addr); } }catch(Exception e) { e.printStackTrace(); } } }
输出
获得的输出如下所示 -
Table records: First Name: Peter, Last Name: Jones, Address: 482 Rush St., Apt. 402 First Name: Bernice, Last Name: Smith, Address: 916 Maple Dr. First Name: Grace, Last Name: Peterson, Address: 16055 Seminole Ave. First Name: Walter, Last Name: Brown, Address: 8602 1st St. First Name: ReddyParts, Inc., Last Name: , Address: 38 Industrial Blvd. First Name: Parts-to-go, Ltd., Last Name: , Address: 213B Commerce Park.
import mysql.connector #建立连接 connection = mysql.connector.connect( host='localhost', user='root', password='password', database='tut' ) cursorObj = connection.cursor() union_query = f""" SELECT fname, lname, addr FROM prospect UNION SELECT first_name, last_name, address FROM customer UNION SELECT company, '', street FROM vendor; """ cursorObj.execute(union_query) # 获取所有符合条件的行 filtered_rows = cursorObj.fetchall() for row in filtered_rows: print(row) cursorObj.close() connection.close()
输出
以下是上述代码的输出 -
('Peter', 'Jones', '482 Rush St., Apt. 402') ('Bernice', 'Smith', '916 Maple Dr.') ('Grace', 'Peterson', '16055 Seminole Ave.') ('Walter', 'Brown', '8602 1st St.') ('ReddyParts, Inc.', '', '38 Industrial Blvd.') ('Parts-to-go, Ltd.', '', '213B Commerce Park.')