mysql-4:SQL的解析顺序

news2024/12/27 0:41:26

SQL语句的解析顺序

文章目录

  • SQL语句的解析顺序
    • 编写顺序与解析顺序
    • 解析顺序关键字
      • FROM
      • ON
      • OUTER JOIN
      • WHERE
      • GROUP BY
      • HAVING
      • SELECT
      • DISTINCT
      • ORDER BY
      • LIMIT
    • 解析流程
      • 流程分析
        • 流程说明
        • WHERE条件解析顺序

编写顺序与解析顺序

  • 编写顺序
SELECT DISTINCT
< select_list >
FROM
< left_table > < join_type >
JOIN < right_table > ON < join_condition >
WHERE
< where_condition >
GROUP BY
< group_by_list >
HAVING
< having_condition >
ORDER BY
< order_by_condition >
LIMIT < limit_number >
  • 解析顺序
-- 行过滤
1 FROM <left_table>
2 ON <join_condition>
3 <join_type> JOIN <right_table> 第二步和第三步会循环执行
4 WHERE <where_condition> 第四步会循环执行,多个条件的执行顺序是从左往右的。
5 GROUP BY <group_by_list>
6 HAVING <having_condition>
--列过滤
7 SELECT 分组之后才会执行SELECT
8 DISTINCT <select_list>
--排序
9 ORDER BY <order_by_condition>
-- MySQL附加
10 LIMIT <limit_number>9步都是SQL92标准语法。limit是MySQL的独有语法。

解析顺序关键字

FROM

  • 对FROM的左边的表和右边的表计算 笛卡尔积(CROSS JOIN) 。产生虚表VT1:
mysql> select * from product,category;
+-----+-----------------+-------+-------+------+----+--------------+
| pid | pname | price | pdate | cid | id | cname |
+-----+-----------------+-------+-------+------+----+--------------+
| 1 | 泰国大榴莲 | 98 | NULL | 1 | 1 | 国外食品 |
| 1 | 泰国大榴莲 | 98 | NULL | 1 | 2 | 国内食品 |
| 1 | 泰国大榴莲 | 98 | NULL | 1 | 3 | 国内服装 |
| 2 | 泰国大枣 | 38 | NULL | 1 | 1 | 国外食品 |
| 2 | 泰国大枣 | 38 | NULL | 1 | 2 | 国内食品 |
| 2 | 泰国大枣 | 38 | NULL | 1 | 3 | 国内服装 |
| 3 | 新疆切糕 | 68 | NULL | 2 | 1 | 国外食品 |
| 3 | 新疆切糕 | 68 | NULL | 2 | 2 | 国内食品 |
| 3 | 新疆切糕 | 68 | NULL | 2 | 3 | 国内服装 |
| 4 | 十三香 | 10 | NULL | 2 | 1 | 国外食品 |
| 4 | 十三香 | 10 | NULL | 2 | 2 | 国内食品 |
| 4 | 十三香 | 10 | NULL | 2 | 3 | 国内服装 |
| 5 | 泰国大枣 | 20 | NULL | 2 | 1 | 国外食品 |
| 5 | 泰国大枣 | 20 | NULL | 2 | 2 | 国内食品 |
| 5 | 泰国大枣 | 20 | NULL | 2 | 3 | 国内服装 |
| 6 | 泰国大枣 | 98 | NULL | 20 | 1 | 国外食品 |
| 6 | 泰国大枣 | 98 | NULL | 20 | 2 | 国内食品 |
| 6 | 泰国大枣 | 98 | NULL | 20 | 3 | 国内服装 |
| 7 | iPhone手机 | 800 | NULL | 30 | 1 | 国外食品 |
| 7 | iPhone手机 | 800 | NULL | 30 | 2 | 国内食品 |
| 7 | iPhone手机 | 800 | NULL | 30 | 3 | 国内服装 |
+-----+-----------------+-------+-------+------+----+--------------+
21 rows in set (0.00 sec)

通过在 FROM 子句中列出多个表格,你可以执行一个叫做交叉连接(Cross Join)的操作,它会将product,category两个表的每一行进行组合,生成一个包含所有可能组合的结果集。

ON

  • 对虚表VT1进行ON筛选,只有那些符合的行才会被记录在虚表VT2中:
mysql> select * from product a, category b where a.cid=b.id;
+-----+-----------------+-------+-------+------+----+--------------+
| pid | pname | price | pdate | cid | id | cname |
+-----+-----------------+-------+-------+------+----+--------------+
| 1 | 泰国大榴莲 | 98 | NULL | 1 | 1 | 国外食品 |
| 2 | 泰国大枣 | 38 | NULL | 1 | 1 | 国外食品 |
| 3 | 新疆切糕 | 68 | NULL | 2 | 2 | 国内食品 |
| 4 | 十三香 | 10 | NULL | 2 | 2 | 国内食品 |
| 5 | 泰国大枣 | 20 | NULL | 2 | 2 | 国内食品 |
+-----+-----------------+-------+-------+------+----+--------------+
5 rows in set (0.00 sec)

OUTER JOIN

  • 如果指定了 OUTER JOIN(比如left join、 right join) ,那么保留表中未匹配的行就会作为外部行添加到虚拟表VT2 中,产生虚拟表VT3
  • 如果FROM子句中包含两个以上的表的话,那么就会对上一个join连接产生的结果VT3和下一个表重复执行步骤1~3这三个步骤,一直到处理完所有的表为止
  • 以左表数据为准
mysql> select * from product a left outer join category b on a.cid=b.id; 
+-----+-----------------+-------+-------+------+------+--------------+
| pid | pname | price | pdate | cid | id | cname |
+-----+-----------------+-------+-------+------+------+--------------+
| 1 | 泰国大榴莲 | 98 | NULL | 1 | 1 | 国外食品 |
| 2 | 泰国大枣 | 38 | NULL | 1 | 1 | 国外食品 |
| 3 | 新疆切糕 | 68 | NULL | 2 | 2 | 国内食品 |
| 4 | 十三香 | 10 | NULL | 2 | 2 | 国内食品 |
| 5 | 泰国大枣 | 20 | NULL | 2 | 2 | 国内食品 |
| 6 | 泰国大枣 | 98 | NULL | 20 | NULL | NULL |
| 7 | iPhone手机 | 800 | NULL | 30 | NULL | NULL |
+-----+-----------------+-------+-------+------+------+--------------+
7 rows in set (0.00 sec)
  • 以右表数据为准
mysql> select * from product a right outer join category b on a.cid=b.id; 
+------+-----------------+-------+-------+------+----+--------------+
| pid | pname | price | pdate | cid | id | cname |
+------+-----------------+-------+-------+------+----+--------------+
| 1 | 泰国大榴莲 | 98 | NULL | 1 | 1 | 国外食品 |
| 2 | 泰国大枣 | 38 | NULL | 1 | 1 | 国外食品 |
| 3 | 新疆切糕 | 68 | NULL | 2 | 2 | 国内食品 |
| 4 | 十三香 | 10 | NULL | 2 | 2 | 国内食品 |
| 5 | 泰国大枣 | 20 | NULL | 2 | 2 | 国内食品 |
| NULL | NULL | NULL | NULL | NULL | 3 | 国内服装 |
+------+-----------------+-------+-------+------+----+--------------+
6 rows in set (0.00 sec)

WHERE

  • 对虚拟表VT3 进行WHERE条件过滤。只有符合的记录才会被插入到虚拟表VT4 中

此时因为分组,不能使用聚合运算;也不能使用SELECT中创建的别名;

  • 与ON的区别
    • 如果有外部列,ON针对过滤的是关联表,主表(保留表)会返回所有的列;
    • 如果没有添加外部列,两者的效果是一样的;
  • 应用
    • 对主表的过滤应该放在WHERE;
    • 对于关联表,先条件查询后连接则用ON,先连接后条件查询则用WHERE;
mysql> select * from product a left outer join category b on a.cid=b.id where
a.pname='泰国大枣';
+-----+--------------+-------+-------+------+------+--------------+
| pid | pname | price | pdate | cid | id | cname |
+-----+--------------+-------+-------+------+------+--------------+
| 2 | 泰国大枣 | 38 | NULL | 1 | 1 | 国外食品 |
| 5 | 泰国大枣 | 20 | NULL | 2 | 2 | 国内食品 |
| 6 | 泰国大枣 | 98 | NULL | 20 | NULL | NULL |
+-----+--------------+-------+-------+------+------+--------------+
3 rows in set (0.00 sec)

GROUP BY

  • 根据group by子句中的列,对VT4中的记录进行分组操作,产生虚拟表VT5。

注意:其后处理过程的语句,如SELECT,HAVING,所用到的列必须包含在GROUP BY中。对于没有出现的,得用聚合函数;

  • 原因:
    • GROUP BY改变了对表的引用,将其转换为新的引用方式,能够对其进行下一级逻辑操作的列会减少;
  • 理解
    • 根据分组字段,将具有相同分组字段的记录归并成一条记录,因为每一个分组只能返回一条记录,除非是被过滤掉了,而不在分组字段里面的字段可能会有多个值,多个值是无法放进一条记录的,所以必须通过聚合函数将这些具有多值的列转换成单值;
mysql> select * from product a left outer join category b on a.cid=b.id where
a.pname='泰国大枣' group by a.price;
+-----+--------------+-------+-------+------+------+--------------+
| pid | pname | price | pdate | cid | id | cname |
+-----+--------------+-------+-------+------+------+--------------+
| 5 | 泰国大枣 | 20 | NULL | 2 | 2 | 国内食品 |
| 2 | 泰国大枣 | 38 | NULL | 1 | 1 | 国外食品 |
| 6 | 泰国大枣 | 98 | NULL | 20 | NULL | NULL |
+-----+--------------+-------+-------+------+------+--------------+
3 rows in set (0.01 sec)

HAVING

  • 对虚拟表VT5 应用having过滤,只有符合的记录才会被插入到虚拟表VT6 中。
mysql> select * from product a left outer join category b on a.cid=b.id where
a.pname='泰国大枣' group by a.price having b.id <=2;
+-----+--------------+-------+-------+------+------+--------------+
| pid | pname | price | pdate | cid | id | cname |
+-----+--------------+-------+-------+------+------+--------------+
| 5 | 泰国大枣 | 20 | NULL | 2 | 2 | 国内食品 |
| 2 | 泰国大枣 | 38 | NULL | 1 | 1 | 国外食品 |
+-----+--------------+-------+-------+------+------+--------------+
2 rows in set (0.00 sec)

SELECT

  • 这个子句对SELECT子句中的元素进行处理,生成VT5表。
  • (5-J1)计算表达式计算SELECT 子句中的表达式,生成VT5-J1

DISTINCT

  • 寻找VT5-1中的重复列,并删掉,生成VT5-J2
  • 如果在查询中指定了DISTINCT子句,则会创建一张内存临时表(如果内存放不下,就需要存放在硬盘了)。这张临时表的表结构和上一步产生的虚拟表VT5是一样的,不同的是对进行DISTINCT操作的列增
    加了一个唯一索引,以此来除重复数据。
mysql> select distinct a.pname from product a left outer join category b on
a.cid=b.id where a.pname='泰国大枣' group by a.price ;
+--------------+
| pname |
+--------------+
| 泰国大枣 |
+--------------+
1 row in set (0.00 sec)

ORDER BY

  • 从 VT5-J2 中的表中,根据ORDER BY 子句的条件对结果进行排序,生成VT6表

唯一可使用SELECT中别名的地方

mysql> select * from product a left outer join category b on a.cid=b.id where
a.pname='泰国大枣' group by a.price having b.id <=2 order by b.id;
+-----+--------------+-------+-------+------+------+--------------+
| pid | pname | price | pdate | cid | id | cname |
+-----+--------------+-------+-------+------+------+--------------+
| 2 | 泰国大枣 | 38 | NULL | 1 | 1 | 国外食品 |
| 5 | 泰国大枣 | 20 | NULL | 2 | 2 | 国内食品 |
+-----+--------------+-------+-------+------+------+--------------+
2 rows in set (0.00 sec)

LIMIT

  • LIMIT子句从上一步得到的 VT6虚拟表 中选出从指定位置开始的指定行数据

MySQL特有
offset 和 rows 的正负带来的影响;

  • 当偏移量很大时效率是很低的,可以这么做:
    • 采用子查询的方式优化 ,在子查询里先从索引获取到最大id,然后倒序排,再取N行结果集
    • 采用INNER JOIN优化 ,JOIN子句里也优先从索引获取ID列表,然后直接关联查询获得最终结果
mysql> select * from product a left outer join category b on a.cid=b.id where
a.pname='泰国大枣' group by a.price having b.id <=2 order by b.id limit 1;
+-----+--------------+-------+-------+------+-
-----+--------------+
| pid | pname | price | pdate | cid | id | cname |
+-----+--------------+-------+-------+------+------+--------------+
| 2 | 泰国大枣 | 38 | NULL | 1 | 1 | 国外食品 |
+-----+--------------+-------+-------+------+------+--------------+
1 row in set (0.00 sec)

解析流程

在这里插入图片描述

流程分析

    1. FROM(将最近的两张表,进行笛卡尔积)—VT1
    1. ON(将VT1按照它的条件进行过滤)—VT2
    1. LEFT JOIN(保留左表的记录)—VT3
    1. WHERE(过滤VT3中的记录)–VT4…VTn
    1. GROUP BY(对VT4的记录进行分组)—VT5
    1. HAVING(对VT5中的记录进行过滤)—VT6
    1. SELECT(对VT6中的记录,选取指定的列)–VT7
    1. ORDER BY(对VT7的记录进行排序)–VT8
    1. LIMIT(对排序之后的值进行分页)–MySQL特有的语法
流程说明
  • 单表查询:根据 WHERE 条件过滤表中的记录,形成中间表(这个中间表对用户是不可见的);然后根据 SELECT 的选择列选择相应的列进行返回最终结果。
  • 两表连接查询:对两表求积(笛卡尔积)并用 ON 条件和连接类型进行过滤形成中间表;然后根据WHERE条件过滤中间表的记录,并根据 SELECT 指定的列返回查询结果。

笛卡尔积:行相乘、列相加。

  • 多表连接查询:先对第一个和第二个表按照两表连接做查询,然后用查询结果和第三个表做连接查询,以此类推,直到所有的表都连接上为止,最终形成一个中间的结果表,然后根据WHERE条件过滤中间表的记录,并根据SELECT指定的列返回查询结果。
WHERE条件解析顺序
  • MySQL :从左往右去执行 WHERE 条件的。
  • Oracle :从右往左去执行 WHERE 条件的。

写WHERE条件的时候,优先级高的部分要去编写过滤力度最大的条件语句

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1040121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用ALU,RAM,寄存器打造一个CPU

CPU简介 计算机的心脏是中央处理单元&#xff0c;简称“CPU” 。这篇文章就利用前几篇文章中提到过的ALU,RAM,寄存器组件做一个CPU。 CPU负责运行程序&#xff0c;程序是由一个个操作组成的&#xff0c;这些操作叫做指令&#xff0c;因为他们“指示”计算机要做什么. CPU能做什…

登录业务实现 - token登录鉴权

登录业务实现&#xff1a; 登录成功/失败实现 -> pinia管理用户数据及数据持久化 -> 不同登录状态的模板适配 -> 请求拦截器携带token&#xff08;登录鉴权&#xff09; -> 退出登录实现 -> token失效&#xff08;401响应拦截&#xff09; 1. 登录成…

超详细C语言实现——通讯录

目录 一、介绍 二、源代码 test.c: Contact.c: Contact.h: 代码运行结果&#xff1a; 三、开始实现 1.基本框架&#xff1a; 2.添加联系人&#xff1a; 3.显示联系人信息&#xff1a; 4.删除联系人信息&#xff1a; 5.查看指定联系人信息&#xff1a; 6.修改联系人…

多维时序 | MATLAB实现PSO-BP多变量时间序列预测(粒子群优化BP神经网络)

多维时序 | MATLAB实现PSO-BP多变量时间序列预测(粒子群优化BP神经网络) 目录 多维时序 | MATLAB实现PSO-BP多变量时间序列预测(粒子群优化BP神经网络)效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现PSO-BP粒子群优化BP神经网络多变量时间序列预测&#xff…

初学vue.js

准备Vue.js环境 ① 下载环境&#xff1a; javaScript语言的程序包&#xff1a;外部js文件 对于Vue来说&#xff0c;导入Vue的外部js文件就能够使用Vue框架了。 Vue框架的js文件获取: 官网提供的下载地址&#xff1a;https://cdn.jsdelivr.net/npm/vue/dist/vue.js ②导入环境…

Kotlin中使用Java数据类时引发的一个Bug

文章目录 基础复习&#xff1a;Kotlin语言中的对象比较背景问题出现解决方式方式一方式二 基础复习&#xff1a;Kotlin语言中的对象比较 比较对象的内容是否相等 ( 或者 equals )&#xff1a;Kotlin 中的操作符 和 equals效果相同 &#xff0c;都用于比较对象的内容是否相等,…

Wespeaker框架数据集准备(1)

1. 数据集准备(Data preparation) 进入wespeaker目录文件/home/username/wespeaker/examples/voxceleb/v2 对run.sh文件进行编辑 vim run.sh 可以看到run.sh里面的配置内容 #数据集下载&#xff0c;解压 stage1 #插入噪音&#xff0c;制作音频文件 stop_stage2 #数据集放置…

递归算法讲解,深度理解递归

首先最重要的就是要说明递归思想的作用&#xff0c;在后面学习的高级数据接口&#xff0c;树和图中&#xff0c;都需要用到递归&#xff0c;即深度优先搜索&#xff0c;如果递归掌握的不好&#xff0c;后面的数据结构将举步为艰。 加油 首先看下如何下面两个方法有什么区别&a…

基于Java+SpringBoot+Vue3+Uniapp前后端分离考试学习一体机设计与实现2.0版本(视频讲解,已发布上线)

博主介绍&#xff1a;✌全网粉丝4W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

Allegro如何将丝印文字Change到任意层面操作指导

Allegro如何将丝印文字Change到任意层面操作指导 在用Allegro进行PCB设计的时候,有时需要将丝印文字change到其它层面,如下图 可以看到丝印文字是属于REFDES这个Class的 如果需要把丝印文字change层面,只支持REFDES中以下的层面中来change

【深入浅出设计模式--命令模式】

深入浅出设计模式--命令模式 一、背景二、问题三、解决方案四、试用场景总结五、后记 一、背景 命令模式是一种行为设计模式&#xff0c;它可以将用户的命令请求转化为一个包含有相关参数信息的对象&#xff0c;命令的发送者不需要知道接收者是如何处理这条命令&#xff0c;多个…

Qt Chats(一)绘制折线图

1、一个简单的QChart绘图程序 Qt Charts基于Qt的Graphics View架构&#xff0c;其核心组件是QChartView 和 QChart QChartView是显示图标的视图&#xff0c;基类为QGraphicsViewQChart的基类是QGraphicsltem QChart类继承关系 QPolarChart 用于绘制 极坐标图的图表类 1.项目…

(自学)黑客技术——网络安全

如果你想自学网络安全&#xff0c;首先你必须了解什么是网络安全&#xff01;&#xff0c;什么是黑客&#xff01;&#xff01; 1.无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面性&#xff0c;例如 Web 安全技术&#xff0c;既有 Web 渗透2.也有 Web 防…

基于微信小程序的婚庆婚纱摄影预约平台(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

彩色文本进度条

动态加色打印&#xff0c;\033控制&#xff0c;显示进行到的百分比&#xff0c;实时更新总共用时。 (本笔记适合能熟练应用字符串和循环技能的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程…

开发者必备!如何将闲置iPad Pro打造为编程工具,使用VS Code编写代码

文章目录 前言1. 本地环境配置2. 内网穿透2.1 安装cpolar内网穿透(支持一键自动安装脚本)2.2 创建HTTP隧道 3. 测试远程访问4. 配置固定二级子域名4.1 保留二级子域名4.2 配置二级子域名 5. 测试使用固定二级子域名远程访问6. ipad pro通过软件远程vscode6.1 创建TCP隧道 7. ip…

数据结构 | 队列

队列&#xff08;First In First Out&#xff09; 顺序队列 #include <iostream>class MyQueue {private:// store elementsvector<int> data; // a pointer to indicate the start positionint p_start; public:MyQueue() {p_start 0;}/** In…

爬虫怎么批量采集完成任务

目录 一、了解网络爬虫 二、Python与网络爬虫 三、批量采集任务的实现 1.确定采集网站及关键词 2.安装相关库 3.发送请求并获取响应 4.解析HTML文档 5.提取文章内容 6.保存文章内容 7.循环采集多篇文章 8.增加异常处理机制 9.优化代码性能 四、注意事项 总结 在当…

UNet网络模型学习总结

github&#xff1a;Machine_Learning/网络模型/UNet at main golitter/Machine_Learning (github.com) 因为VOC数据集太大&#xff0c;上传github很慢&#xff0c;所以就没有上传VOC数据&#xff0c;只有参考的目录位置。 数据集自行下载&#xff1a;https://host.robots.ox.…

顾曼宁(顾曼):漂流伞创始人与杭州高层次人才的杰出代表

杭州&#xff0c;这座以创新与活力为标签的城市&#xff0c;吸引了无数优秀的人才。在这座城市中&#xff0c;一位杰出的女性企业家以其独特的创业智慧和卓越的领导力&#xff0c;成为了杭州高层次人才的杰出代表之一&#xff0c;她的名字叫顾曼宁&#xff08;顾曼&#xff09;…