MySQL 入门教程
  • 教程目录
  • 第一章 基础教程
    • 第一节 入门
      • 1.1 安装
      • 1.2 示例数据库
    • 第二节 查询数据
      • 2.1 SELECT 语句
      • 2.2 SELECT DISTINCT 语句
    • 第三节 过滤数据
      • 3.1 WHERE 子句
      • 3.2 AND 运算符
      • 3.3 OR 运算符
      • 3.4 IN 运算符
      • 3.5 BETWEEN 运算符
      • 3.6 LIKE 运算符
      • 3.7 LIMIT 子句
      • 3.8 IS NULL 运算符
    • 第四节 数据排序
      • 4.1 ORDER BY 子句
      • 4.1 自然排序
    • 第五节 连接表
      • 5.1 别名
      • 5.2 INNER JOIN
      • 5.3 LEFT JOIN
      • 5.4 自连接
      • 5.5 CROSS JOIN
    • 第六节 分组数据
      • 6.1 GROUP BY子句
      • 6.2 HAVING 子句
    • 第七节 子查询,派生表和通用表达式
      • 7.1 子查询
      • 7.2 派生表
      • 7.3 公共表表达式
      • 7.4 递归 CTE
    • 第八节 集合操作符
      • 8.1 UNION 和 UNION ALL
      • 8.2 INTERSECT 模拟
    • 第九节 修改数据
      • 9.1 INSERT 语句
      • 9.2 INSERT IGNORE
      • 9.3 UPDATE 语句
      • 9.4 UPDATE JOIN 语句
      • 9.5 DELETE
      • 9.6 ON DELETE CASCADE.
      • 9.7 DELETE JOIN
      • 9.8 REPLACE 语句
      • 9.9 PREPARE 语句
    • 第十节 事务
      • 10.1 事务介绍
      • 10.2 表锁定
    • 第十一节 管理数据库和表
      • 11.1 数据库管理
      • 11.2 MySQL 表类型
      • 11.3 CREATE TABLE
      • 11.4 序列
      • 11.5 ALTER TABLE
      • 11.6 重命名表
      • 11.7 从表中删除列
      • 11.8 向表中添加新列
      • 11.9 删除表
      • 11.10 临时表
      • 11.11 TRUNCATE TABLE
    • 第十二节 索引
      • 12.1 管理索引
      • 12.1 UNIQUE 索引
    • 第十三节 数据类型
      • 13.1 INT
      • 13.2 DECIMAL
      • 13.3 BIT
      • 13.4 BOOLEAN
      • 13.5 CHAR
      • 13.6 VARCHAR
      • 13.7 TEXT
      • 13.8 DATE
      • 13.9 TIME
      • 13.10 DATETIME
      • 13.11 TIMESTAMP
      • 13.12 JSON
      • 13.13 ENUM
    • 第十四节 约束
      • 14.1 NOT NULL 约束
      • 14.2 主键约束
      • 14.2 外键约束
      • 14.4 UNIQUE 约束
      • 14.5 CHECK 约束
    • 第十五节 全球化
      • 15.1 字符集
      • 15.2 校对规则
    • 第十六节 导入和导出
      • 16.1 导入 CSV 文件
      • 16.2 导出为 CSV
  • 第二章 技巧
    • CTE 简介
    • 递归 CTE
    • 邻接列表模型和层次结构
    • 获取行数
    • 比较表
    • 找重复值
    • 删除重复行
    • UUID 和主键
    • 复制表数据
    • 变量
    • 生成列
    • 连续行比较
    • 更改存储引擎
    • 基于正则表达式的搜索
    • row_number 模拟
    • 随机选择记录
    • 选择第 n 个最高纪录
    • 重置自动增量值
    • MariaDB 与 MySQL 比较
    • 间隔
    • NULL 详细和应用
    • 获取今天的日期
    • 将NULL值映射到有意义的值
    • 注释
  • 第三章 存储过程
    • 简介
    • 入门
    • 变量
    • 参数
    • 返回多个值
    • IF语句
    • CASE语句
    • IF和CASE语句的技巧
    • 循环
    • 游标
    • 列出存储过程
    • 错误处理
    • SIGNAL 和 ESIGNAL 语句
    • 存储函数
  • 第四章 触发器
    • 实现
    • 创建
    • 创建多个触发器
    • 管理
    • 计划事件
    • 修改事件
  • 第五章 视图
    • 简介
    • 实现和限制
    • 创建
    • 可更新视图
    • 确保视图一致性
    • 检查选项子句
    • 管理
  • 第六章 全文搜索
    • 简介
    • 定义索引
    • 自然语言全文搜索
    • 布尔全文搜索
    • 查询扩展
    • ngram全文解析器
  • 第七章 函数
  • 第八章 管理
    • 访问控制系统入门
    • 创建用户
    • 授予权限
    • 撤销权限
    • 角色管理
    • 删除用户
    • 维护数据库表
    • 备份数据库
    • 列出数据库
    • 列出表
    • 列出表的列
    • 列出用户
Powered by GitBook
On this page
  • 1. MySQL派生表介绍
  • 2. 简单的MySQL派生表示例
  • 3. 一个更复杂的MySQL派生表示例

Was this helpful?

  1. 第一章 基础教程
  2. 第七节 子查询,派生表和通用表达式

7.2 派生表

Previous7.1 子查询Next7.3 公共表表达式

Last updated 5 years ago

Was this helpful?

在本教程中,您将了解和学习MySQL派生表以及如何简化复杂查询。

1. MySQL派生表介绍

派生表是从返回的虚拟表。派生表类似于临时表,但是在SELECT语句中使用派生表比简单得多,因为它不需要创建临时表的步骤。

术语:*派生表*和通常可互换使用。当SELECT语句的FROM子句中使用独立子查询时,我们将其称为派生表。

以下说明了使用派生表的查询:

请注意,独立子查询是一个子查询,可独立于包含该语句的执行语句。

Every derived table must have its own alias.

以下说明了使用派生表的SQL语句:

SELECT 
    column_list
FROM
    (SELECT 
        column_list
    FROM
        table_1) derived_table_name;
WHERE derived_table_name.c1 > 0;

2. 简单的MySQL派生表示例

参考以下查询语句 -

SELECT 
    productCode, 
    ROUND(SUM(quantityOrdered * priceEach)) sales
FROM
    orderdetails
        INNER JOIN
    orders USING (orderNumber)
WHERE
    YEAR(shippedDate) = 2013
GROUP BY productCode
ORDER BY sales DESC
LIMIT 5;

执行上面查询语句,得到以下结果 -

+-------------+--------+
| productCode | sales  |
+-------------+--------+
| S18_3232    | 103480 |
| S10_1949    | 67985  |
| S12_1108    | 59852  |
| S12_3891    | 57403  |
| S12_1099    | 56462  |
+-------------+--------+
5 rows in set

您可以使用此查询的结果作为派生表,并将其与products表相关联,products表的结构如下所示:

mysql> desc products;
+--------------------+---------------+------+-----+---------+-------+
| Field              | Type          | Null | Key | Default | Extra |
+--------------------+---------------+------+-----+---------+-------+
| productCode        | varchar(15)   | NO   | PRI |         |       |
| productName        | varchar(70)   | NO   |     | NULL    |       |
| productLine        | varchar(50)   | NO   | MUL | NULL    |       |
| productScale       | varchar(10)   | NO   |     | NULL    |       |
| productVendor      | varchar(50)   | NO   |     | NULL    |       |
| productDescription | text          | NO   |     | NULL    |       |
| quantityInStock    | smallint(6)   | NO   |     | NULL    |       |
| buyPrice           | decimal(10,2) | NO   |     | NULL    |       |
| MSRP               | decimal(10,2) | NO   |     | NULL    |       |
+--------------------+---------------+------+-----+---------+-------+
9 rows in set

参考以下查询语句 -

SELECT 
    productName, sales
FROM
    (SELECT 
        productCode, 
        ROUND(SUM(quantityOrdered * priceEach)) sales
    FROM
        orderdetails
    INNER JOIN orders USING (orderNumber)
    WHERE
        YEAR(shippedDate) = 2013
    GROUP BY productCode
    ORDER BY sales DESC
    LIMIT 5) top5products2013
INNER JOIN
    products USING (productCode);

执行上面查询语句,得到以下结果 -

+-----------------------------+--------+
| productName                 | sales  |
+-----------------------------+--------+
| 1992 Ferrari 360 Spider red | 103480 |
| 1952 Alpine Renault 1300    | 67985  |
| 2001 Ferrari Enzo           | 59852  |
| 1969 Ford Falcon            | 57403  |
| 1968 Ford Mustang           | 56462  |
+-----------------------------+--------+
5 rows in set

在上面这个例子中:

  • 首先,执行子查询来创建一个结果集或派生表。

  • 然后,在productCode列上使用products表连接top5product2013派生表的外部查询。

3. 一个更复杂的MySQL派生表示例

假设必须将2013年的客户分为3组:铂金,白金和白银。 此外,需要了解每个组中的客户数量,具体情况如下:

  • 订单总额大于100000的为铂金客户;

  • 订单总额为10000至100000的为黄金客户

  • 订单总额为小于10000的为银牌客户

SELECT 
    customerNumber,
    ROUND(SUM(quantityOrdered * priceEach)) sales,
    (CASE
        WHEN SUM(quantityOrdered * priceEach) < 10000 THEN 'Silver'
        WHEN SUM(quantityOrdered * priceEach) BETWEEN 10000 AND 100000 THEN 'Gold'
        WHEN SUM(quantityOrdered * priceEach) > 100000 THEN 'Platinum'
    END) customerGroup
FROM
    orderdetails
        INNER JOIN
    orders USING (orderNumber)
WHERE
    YEAR(shippedDate) = 2013
GROUP BY customerNumber 
ORDER BY sales DESC;

以下是查询的输出:

+----------------+--------+---------------+
| customerNumber | sales  | customerGroup |
+----------------+--------+---------------+
|            141 | 189840 | Platinum      |
|            124 | 167783 | Platinum      |
|            148 | 150123 | Platinum      |
|            151 | 117635 | Platinum      |
|            320 | 93565  | Gold          |
|            278 | 89876  | Gold          |
|            161 | 89419  | Gold          |
| ************此处省略了一大波数据 *********|
|            219 | 4466   | Silver        |
|            323 | 2880   | Silver        |
|            381 | 2756   | Silver        |
+----------------+--------+---------------+

然后,可以使用此查询作为派生表,并按如下所示进行分组:

SELECT 
    customerGroup, 
    COUNT(cg.customerGroup) AS groupCount
FROM
    (SELECT 
        customerNumber,
            ROUND(SUM(quantityOrdered * priceEach)) sales,
            (CASE
                WHEN SUM(quantityOrdered * priceEach) < 10000 THEN 'Silver'
                WHEN SUM(quantityOrdered * priceEach) BETWEEN 10000 AND 100000 THEN 'Gold'
                WHEN SUM(quantityOrdered * priceEach) > 100000 THEN 'Platinum'
            END) customerGroup
    FROM
        orderdetails
    INNER JOIN orders USING (orderNumber)
    WHERE
        YEAR(shippedDate) = 2013
    GROUP BY customerNumber) cg
GROUP BY cg.customerGroup;

执行上面查询语句,得到以下结果 -

+---------------+------------+
| customerGroup | groupCount |
+---------------+------------+
| Gold          |         61 |
| Platinum      |          4 |
| Silver        |          8 |
+---------------+------------+
3 rows in set

在本教程中,您已经学会了如何使用FROM子句中的子查询作为MySQL派生表来简化复杂查询。

与子查询不同,派生表必须具有,以便稍后在查询中引用其名称。 如果派生表没有别名,MySQL将发出以下错误:

以下查询从中的orders表和orderdetails表中获得2013年销售收入最高的前5名产品:

要构建此查询,首先,您需要使用表达式和子句将每个客户放入相应的分组中,如下所示:

别名
示例数据库(yiibaidb)
CASE
GROUP BY
SELECT语句
临时表
子查询
img
img