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

我们可以将 WHERE 子句与 UNION 操作符一起使用,以在组合之前过滤每个 SELECT 语句的结果。

语法

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

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.

带有 ORDER BY 子句的 UNION

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

语法

以下是使用带有 ORDER BY 子句的 UNION 操作符的基本语法:

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.

使用客户端程序的 UNION 操作符

除了直接在 MySQL 服务器中应用 MySQL 表的 UNION 操作符外,我们还可以使用客户端程序在 MySQL 表上应用 UNION 操作。

语法

以下是各种编程语言中 MySQL 表中 UNION 操作符的语法:

要通过 PHP 程序使用 UNION 操作符组合表,我们需要使用名为query()mysqli 函数执行带有 UNION 操作符的 SQL 语句,如下所示:

$sql = "SELECT column_name(s) FROM table1 UNION SELECT column_name(s) 
FROM table2";
$mysqli->query($sql);

要通过 PHP 程序使用 UNION 操作符组合表,我们需要使用名为query()mysql2 函数执行带有 UNION 操作符的 SQL 语句,如下所示:

sql= " SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2";
con.query(sql);

要通过 PHP 程序使用 UNION 操作符组合表,我们需要使用名为executeQuery()JDBC 类型 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: \n"); while($row = $result->fetch_assoc()) { printf("First Name %s, Last Name: %s, Address %s", $row["fname"], $row["lname"], $row["addr"],); printf("\n"); } } 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"
});

  //Connecting to MySQL
  con.connect(function (err) {
  if (err) throw err;
  console.log("Connected!");
  console.log("--------------------------");

  //Creating a Database
  sql = "create database TUTORIALS"
  con.query(sql);

  //Select database
  sql = "USE TUTORIALS"
  con.query(sql);

  //Creating PROSPECT table
  sql = "CREATE TABLE PROSPECT( fname varchar(400), lname varchar(400), addr varchar(200));"
  con.query(sql);

  //Inserting Records
  sql = "INSERT INTO PROSPECT (fname, lname, addr) VALUES ('peter', 'Jones', '482 Rush St., Apt. 402'), ('Bernice', 'Smith', '916 Maple Dr.');"
  con.query(sql);

  //Creating CUSTOMER table
  sql = "CREATE TABLE CUSTOMER( last_name varchar(400), first_name varchar(400), address varchar(200));"
  con.query(sql);
  
  //Inserting Records
  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);

  //Creating vendor table
  sql = "CREATE TABLE vendor( company varchar(400), street varchar(400));"
  con.query(sql);

  //Inserting Records
  sql = "INSERT INTO vendor (company, street) VALUES ('ReddyParts, Inc.', '38 Industrial Blvd.'), ('Parts-to-go, Ltd.', '213B Commerce Park.');"
  con.query(sql);

  //Using 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://127.0.0.1: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
#establishing the connection
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)
# Fetching all the rows that meet the criteria
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.')      
广告