- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章从零开始学习SQL查询语句执行顺序由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
SQL查询语句执行顺序如下:
1
2
3
4
5
6
7
8
9
10
|
(7)
SELECT
(8)
DISTINCT
<select_list>
(1)
FROM
<left_table>
(3) <join_type>
JOIN
<right_table>
(2)
ON
<join_condition>
(4)
WHERE
<where_condition>
(5)
GROUP
BY
<group_by_list>
(6)
HAVING
<having_condition>
(9)
ORDER
BY
<order_by_condition>
(10) LIMIT <limit_number>
|
前期准备工作 。
1、新建一个测试数据库 。
1
|
create
database
testData;
|
2、创建测试表,并插入数据如下:
用户表 。
订单表 。
准备SQL逻辑查询测试语句 。
1
2
3
4
5
6
7
8
|
SELECT
a.user_id,
COUNT
(b.order_id)
as
total_orders
FROM
user
as
a
LEFT
JOIN
orders
as
b
ON
a.user_id = b.user_id
WHERE
a.city =
'beijing'
GROUP
BY
a.user_id
HAVING
COUNT
(b.order_id) < 2
ORDER
BY
total_orders
desc
|
使用上述SQL查询语句来获得来自北京,并且订单数少于2的客户,
在这些SQL语句的执行过程中,都会产生一个虚拟表,用来保存SQL语句的执行结果 。
1、执行FROM语句 。
第一步,执行FROM语句。我们首先需要知道最开始从哪个表开始的,这就是FROM告诉我们的。现在有了<left_table>和<right_table>两个表,我们到底从哪个表开始,还是从两个表进行某种联系以后再开始呢?它们之间如何产生联系呢?——笛卡尔积 。
经过FROM语句对两个表执行笛卡尔积,会得到一个虚拟表,VT1(vitual table 1),内容如下:
总共有28(user的记录条数 * orders的记录条数)条记录。这就是VT1的结果,接下来的操作就在VT1的基础上进行 。
2、执行ON过滤 。
执行完笛卡尔积以后,接着就进行ON a.user_id = b.user_id条件过滤,根据ON中指定的条件,去掉那些不符合条件的数据,得到VT2如下:
1
|
select
*
from
user
as
a
inner
JOIN
orders
as
b
ON
a.user_id = b.user_id;
|
3、添加外部行 。
这一步只有在连接类型为OUTER JOIN时才发生,如LEFT OUTER JOIN、RIGHT OUTER JOIN和FULL OUTER JOIN。在大多数的时候,我们都是会省略掉OUTER关键字的,但OUTER表示的就是外部行的概念.
LEFT OUTER JOIN把左表记为保留表:即左表的数据会被全部查询出来,若右表中无对应数据,会用NULL来填充:
RIGHT OUTER JOIN把右表记为保留表:即右表的数据会被全部查询出来,若左表中无对应数据,则用NULL补充; 。
FULL OUTER JOIN把左右表都作为保留表,但在Mysql中不支持全连接,可以通过以下方式实现全连接:
由于我在准备的测试SQL查询逻辑语句中使用的是LEFT JOIN,得到的VT3表如下:
4、执行where条件过滤 。
对添加了外部行的数据进行where条件过滤,只有符合<where_condition>条件的记录会被筛选出来,执行WHERE a.city = 'beijing' 得到VT4如下:
但是在使用WHERE子句时,需要注意以下两点:
1、由于数据还没有分组,因此现在还不能在where过滤条件中使用where_condition=MIN(col)这类对分组统计的过滤; 。
2、由于还没有进行列的选取操作,因此在select中使用列的别名也是不被允许的,如:select city as c from table1 wherec='beijing' 是不允许的 。
5、执行group by分组语句 。
GROU BY子句主要是对使用WHERE子句得到的虚拟表进行分组操作,执行GROUP BY a.user_id得到VT5如下:
6、执行having 。
HAVING子句主要和GROUP BY子句配合使用,对分组得到VT5的数据进行条件过滤,执行 HAVING COUNT(b.order_id) < 2,得到VT6如下:
7、select列表 。
现在才会执行到SELECT子句,不要以为SELECT子句被写在第一行,就是第一个被执行的.
我们执行测试语句中的SELECT a.user_id,user_name,COUNT(b.order_id) as total_orders,从VT6中选择出我们需要的内容,得到VT7如下:
8、执行distinct去重复数据 。
如果在查询中指定了DISTINCT子句,则会创建一张内存临时表(如果内存放不下,就需要存放在硬盘了)。这张临时表的表结构和上一步产生的虚拟表是一样的,不同的是对进行DISTINCT操作的列增加了一个唯一索引,以此来除重复数据。测试SQL中没有DISTINCT字句,所以不会执行 。
9、执行order by字句 。
对虚拟表VT7中的内容按照指定的列进行排序,然后返回一个新的虚拟表,我们执行测试SQL语句中的ORDER BY total_orders DESC ,得到结果如下:
DESC倒序排序,ASC升序排序 。
10、执行limit字句 。
LIMIT子句从上一步得到的虚拟表中选出从指定位置开始的指定行数据,常用来做分页; 。
MySQL数据库的LIMIT支持如下形式的选择:limit n,m 。
表示从第n条记录开始选择m条记录。对于小数据,使用LIMIT子句没有任何问题,当数据量非常大的时候,使用LIMIT n, m是非常低效的。因为LIMIT的机制是每次都是从头开始扫描,如果需要从第60万行开始,读取3条数据,就需要先扫描定位到60万行,然后再进行读取,而扫描的过程是一个非常低效的过程.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://blog.csdn.net/alwayssmile21/article/details/52277854 。
最后此篇关于从零开始学习SQL查询语句执行顺序的文章就讲到这里了,如果你想了解更多关于从零开始学习SQL查询语句执行顺序的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
SQL、PL-SQL 和 T-SQL 之间有什么区别? 谁能解释一下这三者之间的区别,并提供每一个的相关使用场景? 最佳答案 SQL 是一种对集合进行操作的查询语言。 它或多或少是标准化的,几乎所有关
这个问题已经有答案了: What is the difference between SQL, PL-SQL and T-SQL? (6 个回答) 已关闭 9 年前。 我对 SQL 的了解足以完成我的
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列有一个默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任
我有一个可能属于以下类型的字符串 string expected result 15-th-rp 15 15/12-rp 12 15-12-th
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 9年前关闭
我有一个存储过程(称为 sprocGetArticles),它从文章表中返回文章列表。这个存储过程没有任何参数。 用户可以对每篇文章发表评论,我将这些评论存储在由文章 ID 链接的评论表中。 有什么方
我目前正在做一个 *cough*Oracle*cough* 数据库主题。讲师介绍embedded SQL作为让其他语言(例如 C、C++)与(Oracle)数据库交互的方式。 我自己做了一些数据库工作
SQL Server 中 SQL 语句的最大长度是多少?这个长度是否取决于 SQL Server 的版本? 例如,在 DECLARE @SQLStatement NVARCHAR(MAX) = N'S
这个问题已经有答案了: Simple way to transpose columns and rows in SQL? (9 个回答) 已关闭 8 年前。 CallType
预先感谢您对此提供的任何帮助。 假设我有一个查询,可以比较跨年的数据,从某个任意年份开始,永无止境(进入 future ),每年同一时期直到最后一个完整的月份(其特点是一月数据永远不会显示至 2 月
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列的默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任何数
下面是我试图用来检查存储过程是否不存在然后创建过程的 sql。它会抛出一个错误:Incorrect syntax near the keyword 'PROCEDURE' IF NOT EXISTS
我有一个同事声称动态 SQL 在许多情况下比静态 SQL 执行得更快,所以我经常看到 DSQL 到处都是。除了明显的缺点,比如在运行之前无法检测到错误并且更难阅读,这是否准确?当我问他为什么一直使用
来自 lobodava 的动态 SQL 查询是: declare @sql nvarchar(4000) = N';with cteColumnts (ORDINAL_POSITION, CO
使用 SQL Server 中的存储过程执行动态 SQL 命令的现实优点和缺点是什么 EXEC (@SQL) 对比 EXEC SP_EXECUTESQL @SQL ? 最佳答案 sp_executes
我有这个有效的 SQL 查询: select sum(dbos.Points) as Points, dboseasons.Year from dbo.StatLines dbos i
我正在调试一些构建成功运行的 SQL 命令的代码。 然而,在查询结束时,查询结果似乎被写入了一个文本文件。 完整的查询如下 echo SELECT DATE,DATETABLE,DATE,APPDAT
我有一些创建表的 .sql 文件(MS SQL 数据库): 表_1.sql: IF OBJECT_ID (N'my_schema.table1', N'U') IS NOT NULL DROP TAB
我写了下面的 SQL 存储过程,它一直给我错误@pid = SELECT MAX(... 整个过程是: Alter PROCEDURE insert_partyco @pname varchar(20
我在 SQL Server 2005 中有包含两列 Fruit 和 Color 的表,如下所示 Fruit Colour Apple Red Orange
我是一名优秀的程序员,十分优秀!