sql语句的各种关键字解析过程的详细总结

由于最近需要对sql查询性能进行研究,我们研究了SQL语句的解决方案,在花园中,我们写了很多相关文章,大家的重点也不尽相同。详细介绍了一个SQL语句每一个关键字的逐步分析过程,欢迎大家相互学习,SQL语句的解析顺序。

一个简单的SQL语句按照以下顺序进行分析:1后面的表。从标识数据源是这个语句查询。和一些条款,如(1-j1)笛卡尔积,(1-j2)过滤,(1-j3)添加一个外部列,对象被应用后,从过程,生成虚拟表VT1。
(1-j1)笛卡尔积这一步占的笛卡尔积(交叉连接)两个相关表和生成虚拟表vt1-j1。
(1-j2)滤波是基于虚拟表vt1-j1,过滤所有列满足谓词条件,并生成虚拟表vt1-j2。
(1-j3)加外排,如果外部连接使用,不符合上表中的条件将被添加到vt1-j2列,和虚拟表vt1-j3将产生外排。
2。在滤波器在VT1的过程中产生的临时表,及满足WHERE子句中的列插入VT2表。
3条款。集团将与栏目组根据VT2产生表组。产生这种表。
4条款。在这种表具有滤波器的不同群体,和条款,满足有条件加入到VT4表。
5条款。选择处理的元素在SELECT子句生成VT5表。
(5-1)通过计算表达和产生vt5-1 SELECT子句中的表达式的计算
(5-2)重复列在vt5-1和削减它产生vt5-2截然不同的样子
(5-3)过滤出合格的列的ORDERBY子句定义的结果产生vt5-3表。
通过形式的vt5-3和分类根据订单的条件子句的结果从表的VC6的顺序表。

顾客、订单的例子

首先,创建一个客户表并插入以下数据:





客户编号
西蒂


马德里

frndo
马德里

krlos
马德里

mrphs
锡安

创建一个订单表并插入以下数据:





订单编号
客户编号


frndo


frndo


krlos


krlos


krlos


mrphs


无效的

如果我们想查询从马德里订购少于3的客户,并显示他们的订单号,订单将按订单号从小到大排序。
复制代码代码如下所示:
选择c.customerid,计数(o.orderid)作为numorders
从客户为C。
左外连接dbo。订单为O
在c.customerid = o.customerid
在c.city = 'madrid
集团通过c.customerid
具有计数(o.orderid)<3
为了numorders

查询结果如下:





客户编号
numorders




frndo


接下来,我们将详细介绍SQL如何计算结果:from子句

from子句标识需要查询的表。如果指定了表操作,它将从左到右进行处理。每一个表的操作基于一个或两个表将返回一个输出表,左表的输出将是下一个表的操作输入的结果。例如,交叉表的相关操作(1-j1)笛卡尔积,(1-j2)过滤器,和(1-j3)添加的从外部列。句子生成虚拟表VT1。步1-j1:执行笛卡儿积(交叉连接)

笛卡尔积将列出所有可能的组合的两表的行,并生成表vt1-j1。如果左表M列和右表的列,然后vt1-j1表生成笛卡尔积后将m n n列。

一步一步1-j1相当于执行:选择*从客户C交叉连接顺序O

结果如下:(共4×7列)





c.customerid
c.city
o.orderid
o.customerid


马德里

frndo


马德里

frndo


马德里

krlos


马德里

krlos


马德里

krlos


马德里

mrphs


马德里

无效的

frndo
马德里

frndo

frndo
马德里

frndo

frndo
马德里

krlos

frndo
马德里

krlos

frndo
马德里

krlos

frndo
马德里

mrphs

frndo
马德里

无效的

krlos
马德里

frndo

krlos
马德里

frndo

krlos
马德里

krlos

krlos
马德里

krlos

krlos
马德里

krlos

krlos
马德里

mrphs

krlos
马德里

无效的

mrphs
锡安

frndo

mrphs
锡安

frndo

mrphs
锡安

krlos

mrphs
锡安

krlos

mrphs
锡安

krlos

mrphs
锡安

mrphs

mrphs
锡安

nullstep 1-j2:过滤应用,(加盟条件)

过滤是SQL的三个过滤条件的第一个实现。在过滤条件应用于前一步生成的虚拟表(vt1-j1),满足过滤条件和添加到虚拟表vt1-j2.after过滤中的应用,所产生的vt1-j2表如下:





c.customerid
c.city
o.orderid
o.customerid

frndo
马德里

frndo

frndo
马德里

frndo

krlos
马德里

krlos

krlos
马德里

krlos

krlos
马德里

krlos

mrphs
锡安

mrphsstep 1-j3:添加外部列

这一步只会发生在外部连接使用。左(右、或全),您可以标记一个或两个表作为预约表。作为一个预约表,这意味着你想要的所有列在表格里面回来,即使里面的数据不符合的在clause.left外加入马克离开预订表的过滤条件,rightouter加入放在桌子的右边为预约表,全外连接把两表标记为保留表。步1-j3根据虚拟表vt1-j2,加上条件不满足于柱的保留在餐桌上,毫不保留,没有相应的列表,因此,标记为空。此过程中产生的一vt1-j3虚拟表。





c.customerid
c.city
o.orderid
o.customerid


马德里
无效的
无效的

frndo
马德里

frndo

frndo
马德里

frndo

krlos
马德里

krlos

krlos
马德里

krlos

krlos
马德里

krlos

mrphs
锡安

mrphs

如果在from子句中有多个表操作,SQL将从左到右进行处理,左边生成的临时表结果用作右表的输入表。第2步WHERE子句

在滤波器应用到上一步中生成的临时表并生成一个基于在过滤条件的临时表VT2。

注:由于数据是没有分组,你不能使用聚合操作,例如,你不能用这样的一句话,OrderDate = max(订单)。此外,你不能使用SELECT子句中创建的变量的别名,因为选择条款尚未被处理,例如,你不能写这样的一句话:选择年(订单)为orderyear。在orderyear>2008。

应用此过滤器,c.city = 'madrid

所生成的临时表VT2的内容如下:





c.customerid
c.city
o.orderid
o.customerid


马德里
无效的
无效的

frndo
马德里

frndo

frndo
马德里

frndo

krlos
马德里

krlos

krlos
马德里

krlos

krlos
马德里

krlos

在这种情况下,你需要使用c.customerid = o.customerid过滤器中的子句,没有订单的客户过滤出来,在这一步,但在1-j3步骤,它重新加入外部列。然而,因为你只想从马德里返回的客户,你需要过滤的城市中的WHERE子句(在c.city =马德里)。如果将其放在过滤器上,不属于马德里的客户将被添加到外部列中。

这里和地方之间的区别需要在这里解释。主要的区别在于,在过滤器前加入外部列,哪里是后。列过滤掉,将增加在1-j3.if你不需要添加外部列,两滤波器相同。步骤3 GROUP BY子句

这一条款分组数据在上一步中生成的临时表,每行分分只有一组生成虚拟表VT3。VT3表包含所有数据在VT2表和组标识符。

这是生成的临时表VT3如下内容:






c.customerid
c.customerid
c.city
o.orderid
o.customerid



马德里
无效的
无效的

frndo
frndo
马德里

frndo

frndo
马德里

frndo


krlos
马德里

krlos

krlos
krlos
马德里

krlos


krlos
马德里

krlos

SQL最后返回结果,每个包必须返回一个行(除非它是过滤掉),所以当集团通过使用一个SQL语句,该集团背后的处理条款,如选择、HAVING子句只能用于组,由后面的柱,没有集团的背后列必须使用聚合函数(如最大、最小、计数、AVG、等),以确保每个组只返回一行。步骤4 HAVING子句

HAVING子句来过滤前一步生成的临时表和只作用于后组的数据,并满足有条件的组添加到虚拟表VT4。

应用此筛选器时:
复制代码代码如下所示:
HAVING COUNT (O.orderid) < 3

之后,所产生的VT4表的内容如下:




c.customerid
c.customerid
c.city
o.orderid
o.customerid



马德里
无效的
无效的

frndo
frndo
马德里

frndo


frndo
马德里

frndo

需要注意的一点是它使用计数(o.orderid)而不是数量(*)。由于外部列被添加到查询中,计数方法忽略null的列,这将导致您不想要的结果。步骤5选择子句

尽管它出现在SQL语句前,选择在第五步处理,和表的SELECT子句返回将最终返回给调用者。本条款包含三个阶段:(5-1)计算表达式,(5-2)处理不同,(5-3)顶部过滤应用。

Step 5-1 calculation expression

SELECT子句中的表达式可以返回或操作上一步返回的表的基本列。如果SQL语句是一个聚集查询,3步后,你只能用栏目组,您必须使用并非是该组的列在表中的聚集操作。没有一个基本的列必须为别名,如去年一样orderyear(订单)。

注:在SELECT子句中不能使用上一步创建的别名,甚至在选择条款。原因是许多SQL操作同时操作(一次操作),而同时操作不再介绍。因此,别名中创建SELECT子句中只能使用下列条款,如顺序。例如,选择年(订单)为orderyear。为了orderyear。

在这个例子中:
复制代码代码如下所示:
选择c.customerid,计数(o.orderid)作为numorders

其结果将是一个虚表vt5-1:



c.customerid
numorders

fifssa


frndo


对步5-2 DISTINCT子句中的应用:

如果不同的是使用的SQL语句,SQL将删除重复的列生成虚拟表vt5-2。

5-3:应用上面的步骤

顶部的选项是一个函数由T-SQL显示显示多少行。指定数量的列的查询基于顺序在ORDERBY子句定义。这个过程产生一个虚拟表vt5-3。

如上所述,这一步取决于顺序的顺序,以确定哪些列应该显示在前面。如果您没有按结果的顺序指定顺序,而不使用连接子句,则每个返回的结果可能不一致。

在我们的例子中,步5-3略因为我们不要使用热门关键词。步骤6:ORDER BY子句

在上一步返回的虚拟表在这步排序并返回光标VC6根据ORDER BY子句中指定的顺序。ORDERBY子句也是唯一的地方,一个别名可以使用select子句创建。

注意:这一步与以往不同的是,这一步的结果是一个指针,而不是一个table.sql基于集合论。一套不确定行的秩序,它仅仅是一个逻辑组的成员,所以成员的顺序并不重要。与ORDERBY子句的SQL返回一个对象,组织各系根据具体sequence.ansi要求这样一个对象作为光标。理解这对你了解SQL重要的。上面的步骤显示如图所示。



本书的主要内容是指在微软SQL Server 2008的内容:T-SQL查询。如果你想知道更多有关SQL查询相关知识,你可以找这本书,看,我有原始的英文PDF,你可以找到我,如果你想要的话。