MySQL 教程 2.4

MySQL UNION 操作符

本教程为大家介绍 MySQL UNION 操作符的语法和实例。

描述

MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合,并去除重复的行。

UNION 操作符必须由两个或多个 SELECT 语句组成,每个 SELECT 语句的列数和对应位置的数据类型必须相同。

语法

MySQL UNION 操作符语法格式:

SELECT column1, column2, ...
FROM table1
WHERE condition1
UNION
SELECT column1, column2, ...
FROM table2
WHERE condition2
[ORDER BY column1, column2, ...];

参数说明:

  • column1, column2, ... 是你要选择的列的名称,如果使用 * 表示选择所有列。
  • table1, table2, ... 是你要从中查询数据的表的名称。
  • condition1, condition2, ... 是每个 SELECT 语句的过滤条件,是可选的。
  • ORDER BY 子句是一个可选的子句,用于指定合并后的结果集的排序顺序。

    实例

    1. 基本的 UNION 操作:

    SELECT city FROM customers
    UNION
    SELECT city FROM suppliers
    ORDER BY city;

    以上 SQL 语句将选择客户表和供应商表中所有城市的唯一值,并按城市名称升序排序。

    2. 使用过滤条件的 UNION:

    SELECT product_name FROM products WHERE category = 'Electronics'
    UNION
    SELECT product_name FROM products WHERE category = 'Clothing'
    ORDER BY product_name;

    以上 SQL 语句将选择电子产品和服装类别的产品名称,并按产品名称升序排序。

    3. UNION 操作中的列数和数据类型必须相同:

    SELECT first_name, last_name FROM employees
    UNION
    SELECT department_name, NULL FROM departments
    ORDER BY first_name;

    以上 SQL 语句中,departments 表中的 department_name 列被映射到了 employees 表中的 last_name 列,但是列数和数据类型必须相同。

    4. 使用 UNION ALL 不去除重复行:

    SELECT city FROM customers
    UNION ALL
    SELECT city FROM suppliers
    ORDER BY city;

    以上 SQL 语句使用 UNION ALL 将客户表和供应商表中的所有城市合并在一起,不去除重复行。

    UNION 操作符在合并结果集时会去除重复行,而 UNION ALL 不会去除重复行,因此 UNION ALL 的性能可能更好,但如果你确实希望去除重复行,可以使用 UNION。


    演示数据库

    在本教程中,我们将使用 RUNOOB 样本数据库。

    下面是选自 "Websites" 表的数据:

    mysql> SELECT * FROM Websites;
    +----+--------------+---------------------------+-------+---------+
    | id | name         | url                       | alexa | country |
    +----+--------------+---------------------------+-------+---------+
    | 1  | Google       | https://www.google.cm/    | 1     | USA     |
    | 2  | 淘宝          | https://www.taobao.com/   | 13    | CN      |
    | 3  | 菜鸟教程      | http://www.runoob.com/    | 4689  | CN      |
    | 4  | 微博          | http://weibo.com/         | 20    | CN      |
    | 5  | Facebook     | https://www.facebook.com/ | 3     | USA     |
    | 7  | stackoverflow | http://stackoverflow.com/ |   0 | IND     |
    +----+---------------+---------------------------+-------+---------+

    下面是 "apps" APP 的数据:

    mysql> SELECT * FROM apps;
    +----+------------+-------------------------+---------+
    | id | app_name   | url                     | country |
    +----+------------+-------------------------+---------+
    |  1 | QQ APP     | http://im.qq.com/       | CN      |
    |  2 | 微博 APP | http://weibo.com/       | CN      |
    |  3 | 淘宝 APP | https://www.taobao.com/ | CN      |
    +----+------------+-------------------------+---------+
    3 rows in set (0.00 sec)

    SQL UNION 实例

    下面的 SQL 语句从 "Websites" 和 "apps" 表中选取所有不同的country(只有不同的值):

    实例

    SELECT country FROM Websites

    UNION

    SELECT country FROM apps

    ORDER BY country;

    执行以上 SQL 输出结果如下:

    注释:UNION 不能用于列出两个表中所有的country。如果一些网站和APP来自同一个国家,每个国家只会列出一次。UNION 只会选取不同的值。请使用 UNION ALL 来选取重复的值!


    SQL UNION ALL 实例

    下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的country(也有重复的值):

    实例

    SELECT country FROM Websites

    UNION ALL

    SELECT country FROM apps

    ORDER BY country;

    执行以上 SQL 输出结果如下:


    带有 WHERE 的 SQL UNION ALL

    下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的中国(CN)的数据(也有重复的值):

    实例

    SELECT country, name FROM Websites

    WHERE country='CN'

    UNION ALL

    SELECT country, app_name FROM apps

    WHERE country='CN'

    ORDER BY country;

    执行以上 SQL 输出结果如下:

    UNION 语句:用于将不同表中相同列中查询的数据展示出来;(不包括重复数据)

    UNION ALL 语句:用于将不同表中相同列中查询的数据展示出来;(包括重复数据)

    使用形式如下:

    SELECT 列名称 FROM 表名称 UNION SELECT 列名称 FROM 表名称 ORDER BY 列名称;
    SELECT 列名称 FROM 表名称 UNION ALL SELECT 列名称 FROM 表名称 ORDER BY 列名称;

     

    MySQL ORDER BY(排序) 语句

    我们知道从 MySQL 表中使用 SELECT 语句来读取数据。

    如果我们需要对读取的数据进行排序,我们就可以使用 MySQL 的 ORDER BY 子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。

    MySQL ORDER BY(排序) 语句可以按照一个或多个列的值进行升序(ASC)或降序(DESC)排序。

    语法

    以下是 SELECT 语句使用 ORDER BY 子句将查询数据排序后再返回数据:

    SELECT column1, column2, ...
    FROM table_name
    ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;

    参数说明:

    • column1, column2, ... 是你要选择的列的名称,如果使用 * 表示选择所有列。
    • table_name 是你要从中查询数据的表的名称。
    • ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ... 是用于指定排序顺序的子句。ASC 表示升序(默认),DESC 表示降序。

      更多说明:

      • 你可以使用任何字段来作为排序的条件,从而返回排序后的查询结果。
      • 你可以设定多个字段来排序。
      • 你可以使用 ASC 或 DESC 关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。
      • 你可以添加 WHERE...LIKE 子句来设置条件。

        实例

        以下是一些 ORDER BY 子句的使用实例。

        1. 单列排序:

        SELECT * FROM products
        ORDER BY product_name ASC;

        以上 SQL 语句将选择产品表 products 中的所有产品,并按产品名称升序 ASC 排序。

        2. 多列排序:

        SELECT * FROM employees
        ORDER BY department_id ASC, hire_date DESC;

        以上 SQL 语句将选择员工表 employees 中的所有员工,并先按部门 ID 升序 ASC 排序,然后在相同部门中按雇佣日期降序 DESC 排序。

        3. 使用数字表示列的位置:

        SELECT first_name, last_name, salary
        FROM employees
        ORDER BY 3 DESC, 1 ASC;

        以上 SQL 语句将选择员工表 employees 中的名字和工资列,并按第三列(salary)降序 DESC 排序,然后按第一列(first_name)升序 ASC 排序。

        4. 使用表达式排序:

        SELECT product_name, price * discount_rate AS discounted_price
        FROM products
        ORDER BY discounted_price DESC;

        以上 SQL 语句将选择产品表 products 中的产品名称和根据折扣率计算的折扣后价格,并按折扣后价格降序 DESC 排序。

        5. 使用 NULLS FIRST 或 NULLS LAST 处理 NULL 值:

        SELECT product_name, price
        FROM products
        ORDER BY price DESC NULLS LAST;

        以上 SQL 语句将选择产品表 products 中的产品名称和价格,并按价格降序 DESC 排序,将 NULL 值排在最后。

        ORDER BY 子句是一个强大的工具,可以根据不同的业务需求对查询结果进行排序。在实际应用中,注意选择适当的列和排序顺序,以获得符合期望的排序效果。


        在命令提示符中使用 ORDER BY 子句

        以下将在 SELECT 语句中使用 ORDER BY 子句来读取 MySQL 数据表 runoob_tbl 中的数据:

        实例

        尝试以下实例,结果将按升序及降序排列。

        SQL 排序

        mysql> use RUNOOB; Database changed mysql> SELECT * from runoob_tbl ORDER BY submission_date ASC; +-----------+---------------+---------------+-----------------+ | runoob_id | runoob_title | runoob_author | submission_date | +-----------+---------------+---------------+-----------------+ | 3 | 学习 Java | RUNOOB.COM | 2015-05-01 | | 4 | 学习 Python | RUNOOB.COM | 2016-03-06 | | 1 | 学习 PHP | 菜鸟教程 | 2017-04-12 | | 2 | 学习 MySQL | 菜鸟教程 | 2017-04-12 | +-----------+---------------+---------------+-----------------+ 4 rows in set (0.01 sec) mysql> SELECT * from runoob_tbl ORDER BY submission_date DESC; +-----------+---------------+---------------+-----------------+ | runoob_id | runoob_title | runoob_author | submission_date | +-----------+---------------+---------------+-----------------+ | 1 | 学习 PHP | 菜鸟教程 | 2017-04-12 | | 2 | 学习 MySQL | 菜鸟教程 | 2017-04-12 | | 4 | 学习 Python | RUNOOB.COM | 2016-03-06 | | 3 | 学习 Java | RUNOOB.COM | 2015-05-01 | +-----------+---------------+---------------+-----------------+ 4 rows in set (0.01 sec)

        读取 runoob_tbl 表中所有数据并按 submission_date 字段的升序排列。


        在 PHP 脚本中使用 ORDER BY 子句

        你可以使用 PHP 函数的 mysqli_query() 及相同的 SELECT 带上 ORDER BY 子句的命令来获取数据。

        该函数用于执行 SQL 命令,然后通过 PHP 函数 mysqli_fetch_array() 来输出所有查询的数据。

        实例

        尝试以下实例,查询后的数据按 submission_date 字段的降序排列后返回。

        MySQL ORDER BY 测试:

        菜鸟教程 MySQL ORDER BY 测试

        '; echo ''; while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC)) { echo " ". " ". " ". " ". ""; } echo '
        教程 ID标题作者提交日期
        {$row['runoob_id']}{$row['runoob_title']} {$row['runoob_author']} {$row['submission_date']}
        '; mysqli_close($conn); ?>

        输出结果如下图所示:

        MySQL 排序我们知道从 MySQL 表中使用 SQL SELECT 语句来读取:

        MySQL 拼音排序

        如果字符集采用的是 gbk(汉字编码字符集),直接在查询语句后边添加 ORDER BY:

        SELECT * 
        FROM runoob_tbl
        ORDER BY runoob_title;

        如果字符集采用的是 utf8(万国码),需要先对字段进行转码然后排序:

        SELECT * 
        FROM runoob_tbl
        ORDER BY CONVERT(runoob_title using gbk);