博客
关于我
mysql五补充部分:SQL逻辑查询语句执行顺序
阅读量:790 次
发布时间:2023-02-11

本文共 3222 字,大约阅读时间需要 10 分钟。

SELECT语句关键字的定义顺序与执行顺序分析

在数据库查询中,SELECT语句是最常用的数据检索命令,其内部包含了多个关键字,每个关键字都有特定的作用和执行顺序。本文将从定义顺序、执行顺序以及实际操作的角度,详细解析SELECT语句的工作原理。


一 SELECT语句的定义顺序

SELECT语句的基本结构如下:

SELECT [DISTINCT] [列名列表] FROM [左表] [LEFT|RIGHT|FULL] JOIN [右表] ON [连接条件]WHERE [条件] GROUP BY [分组列] HAVING [过滤条件] ORDER BY [排序列] LIMIT [限制条数];

1. 列选择列表

SELECT语句的核心是选择需要返回的列。在实际执行过程中,数据库首先会处理SELECT列表,确定需要获取哪些列。例如:

SELECT customer_id, COUNT(order_id) AS total_ordersFROM table1 AS aLEFT JOIN table2 AS b ON a.customer_id = b.customer_idWHERE a.city = 'hangzhou'GROUP BY a.customer_idHAVING COUNT(b.order_id) < 2ORDER BY total_orders DESC;

二 SELECT语句的执行顺序

SELECT语句的执行过程可以分为以下几个关键步骤:

  • FROM语句执行(笛卡尔积)

    根据FROM关键字,数据库首先会生成左表和右表的笛卡尔积,得到一个虚拟表VT1。例如:

    customer_id city order_id customer_id
    163 hangzhou 1 163
    ... ... ... ...
  • ON条件过滤

    接着,数据库会根据ON条件(连接条件)过滤掉不符合条件的数据,生成虚拟表VT2。例如:

    customer_id city order_id customer_id
    163 hangzhou 1 163
    163 hangzhou 2 163
    ... ... ... ...
  • 外部行的添加(如有)

    如果是LEFT JOIN、RIGHT JOIN或FULL JOIN,数据库会添加外部行。例如,左连接会保留左表未匹配的记录,并将右表匹配的记录连接到这些左表记录中。

  • WHERE过滤

    数据库会对已经生成的虚拟表(如VT3)进行WHERE条件过滤,保留符合条件的记录。例如:

    customer_id city order_id customer_id
    163 hangzhou 1 163
    tx hangzhou 6 tx
  • GROUP BY分组

    数据库会对WHERE结果生成的虚拟表(如VT4)进行分组,默认只保留组内第一条记录。例如:

    customer_id city order_id customer_id
    163 hangzhou 1 163
    baidu hangzhou NULL NULL
    tx hangzhou 6 tx
  • HAVING过滤

    最后,数据库会根据HAVING条件过滤分组后的虚拟表(如VT5)。例如:

    customer_id city order_id customer_id
    baidu hangzhou NULL NULL
    tx hangzhou 6 tx
  • SELECT列选择

    在上述基础上,数据库才会执行SELECT列选择,生成临时表(如VT6)。例如:

    customer_id total_orders
    baidu 0
    tx 1
  • DISTINCT去重(如有)

    如果有DISTINCT关键字,数据库会去除重复的记录,生成去重后的临时表(如VT7)。

  • ORDER BY排序

    数据库会根据指定的排序列(如total_orders DESC),生成最终的排序结果(如VT8)。

  • LIMIT限制

    最后,数据库会根据LIMIT子句限制返回的行数,生成最终的查询结果。


  • 三 准备表和数据

    在实际操作中,需要准备表结构和数据。以下是常用的步骤:

  • 创建测试数据库:

    create database TestDB;
  • 创建测试表:

    CREATE TABLE table1 (    customer_id VARCHAR(10) NOT NULL,    city VARCHAR(10) NOT NULL,    PRIMARY KEY(customer_id)) ENGINE=INNODB DEFAULT CHARSET=UTF8;CREATE TABLE table2 (    order_id INT NOT NULL AUTO_INCREMENT,    customer_id VARCHAR(10),    PRIMARY KEY(order_id)) ENGINE=INNODB DEFAULT CHARSET=UTF8;
  • 插入测试数据:

    INSERT INTO table1(customer_id, city) VALUES('163','hangzhou');INSERT INTO table1(customer_id,city) VALUES('9you','shanghai');INSERT INTO table1(customer_id,city) VALUES('tx','hangzhou');INSERT INTO table1(customer_id,city) VALUES('baidu','hangzhou');INSERT INTO table2(customer_id) VALUES('163');INSERT INTO table2(customer_id) VALUES('163');INSERT INTO table2(customer_id) VALUES('9you');INSERT INTO table2(customer_id) VALUES('9you');INSERT INTO table2(customer_id) VALUES('9you');INSERT INTO table2(customer_id) VALUES('tx');INSERT INTO table2(customer_id) VALUES(NULL);

  • 四 准备SQL逻辑查询测试语句

    根据以上准备工作,以下是测试查询语句:

    SELECT a.customer_id, COUNT(b.order_id) AS total_ordersFROM table1 AS aLEFT JOIN table2 AS b ON a.customer_id = b.customer_idWHERE a.city = 'hangzhou'GROUP BY a.customer_idHAVING COUNT(b.order_id) < 2ORDER BY total_orders DESC;

    五 执行顺序分析

    在实际执行过程中,数据库会通过生成多个虚拟表(VT1至VT8)来完成查询。以下是详细的执行过程:

  • FROM语句执行(笛卡尔积)

    • 生成虚拟表VT1。
  • ON条件过滤

    • 生成虚拟表VT2。
  • 外部行的添加(如有)

    • 生成虚拟表VT3。
  • WHERE过滤

    • 生成虚拟表VT4。
  • GROUP BY分组

    • 生成虚拟表VT5。
  • HAVING过滤

    • 生成虚拟表VT6。
  • SELECT列选择

    • 生成虚拟表VT7。
  • DISTINCT去重(如有)

    • 生成去重后的临时表。
  • ORDER BY排序

    • 生成排序后的虚拟表VT8。
  • LIMIT限制

    • 最终生成查询结果。

  • 通过以上步骤,可以清晰地看到SELECT语句的执行顺序和过程。理解这一点对优化数据库查询和写出高效的SQL语句至关重要。

    转载地址:http://iabfk.baihongyu.com/

    你可能感兴趣的文章
    mysql5.5和5.6版本间的坑
    查看>>
    mysql5.5最简安装教程
    查看>>
    mysql5.6 TIME,DATETIME,TIMESTAMP
    查看>>
    mysql5.6.21重置数据库的root密码
    查看>>
    Mysql5.6主从复制-基于binlog
    查看>>
    MySQL5.6忘记root密码(win平台)
    查看>>
    MySQL5.6的Linux安装shell脚本之二进制安装(一)
    查看>>
    MySQL5.6的zip包安装教程
    查看>>
    mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
    查看>>
    Webpack 基本环境搭建
    查看>>
    mysql5.7 安装版 表不能输入汉字解决方案
    查看>>
    MySQL5.7.18主从复制搭建(一主一从)
    查看>>
    MySQL5.7.19-win64安装启动
    查看>>
    mysql5.7.19安装图解_mysql5.7.19 winx64解压缩版安装配置教程
    查看>>
    MySQL5.7.37windows解压版的安装使用
    查看>>
    mysql5.7免费下载地址
    查看>>
    mysql5.7命令总结
    查看>>
    mysql5.7安装
    查看>>
    mysql5.7性能调优my.ini
    查看>>
    MySQL5.7新增Performance Schema表
    查看>>