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://: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.')      
廣告