sql语句的各个关键字的解析过程详细总结怎么写,sql语句的各个关键字的解析过程详细总结图,SQL语句的各个关键字的解析过程详细总结

sql语句的各个关键字的解析过程详细总结怎么写,sql语句的各个关键字的解析过程详细总结图,SQL语句的各个关键字的解析过程详细总结

最近,我们需要对提高sql查询的性能做一些研究,所以我们研究了sql语句的解析过程。这篇文章是我手机看了各种资料总结出来的。它会一步一步的详细讲述一条sql语句的每个关键字的解析过程。欢迎大家互相学习。

最近,我们需要对提高sql查询的性能做一些研究,所以我们研究了sql语句的求解过程。在园里看完,大家写了很多相关的文章,侧重点不同。这篇文章是我手机看了各种资料总结出来的。它会一步一步的详细讲述一条sql语句的每个关键字的解析过程。欢迎大家互相学习。SQL语句的解析顺序

简单来说,一条sql语句按以下顺序解析:1. FROM FROM后面的表标识了这条语句要查询的数据源。以及一些子句,例如,(1-J1)笛卡尔积,(1-J2)关于滤波,(1-JBOY3乐队)添加外部列,要应用的对象。在FROM过程之后,将生成一个虚拟表VT1。(1-J1)笛卡尔积 此步骤将计算两个相关表的笛卡尔积(交叉连接),并生成虚拟表VT1-J1。(1-J2)ON过滤 这一步基于虚拟表VT1-J1过滤掉所有满足ON谓词条件的列,生成虚拟表VT1-J2。(1-J3)添加外部行 如果使用外部连接,保留表中不满足ON条件的列也将被添加到VT1-J2,并且作为外部行,将生成虚拟表VT1-JBOY3乐队。2. WHERE 过滤VT1过程中生成的临时表,将满足where子句的列插入VT2表中。3. GROUP BY 该子句将根据GROUP BY中的列对VT2中生成的表进行分组。生成VT3表。4. HAVING该子句过滤VT3表中的不同组,满足HAVING条件的子句被添加到VT4表中。5. SELECT此子句处理SELECT子句中的元素,以生成VT5表。(5-1)计算表达式 计算SELECT子句中的表达式,生成VT5-1(5-2)Distinct。在VT5-1中查找重复的列,并删除它们,生成VT5-2(5-3)TOP。从ORDER BY子句中定义的结果中,选择符合条件的列。从VT5-3中的表生成VT5-3表ORDER BY,根据ORDER BY子句的条件对结果进行排序,生成VC6表。

客户,订单的查询例子

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

customerid

城市

FISSA

马德里

FRNDO

马德里

克尔洛斯

马德里

MRPHS

耶路撒冷

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

订单id

customerid

一个

FRNDO

2

FRNDO

克尔洛斯

克尔洛斯

克尔洛斯

MRPHS

假设我们想查询订单编号小于3的马德里客户,并显示他们的订单编号。结果按照从小到大的顺序号排序。复制代码如下:从dbo中选择C.customerid,COUNT(O.orderid)作为numorders。客户为c左外联接dbo。orders as o on c . customerid=o . customerid where c . city=' Madrid ' group by c . customerid having count(o . orderid)3 order by numorders查询结果为:

customerid

numorders

FISSA

0

FRNDO

2

我们将详细描述sql如何计算这个结果:FROM子句

FROM子句标识要查询的表。如果指定了表操作,将从左到右进行处理。基于一个或两个表的每个表操作都将返回一个输出表。左表的输出结果将作为下一次表操作的输入结果。例如,与交叉表相关的操作有(1-J1)笛卡尔积、(1-J2)过滤、(1-JBOY3乐队)添加外部列。FROM语句生成一个虚拟表VT1。Step 1-J1:执行笛卡尔积(CROSS JOIN)

笛卡尔乘积将列出左表和右表的每一行的所有可能组合,以生成表VT1-J1。如果左表有M列,右表有N列,那么笛卡尔积后生成的VT1-J1表将有mn列。

Step 1-J1这个步骤等价于执行:从客户中选择*交叉连接订单O

执行结果为: (共47列)

c .客户id

c .城市

订单编号

o .客户id

FISSA

马德里

一个

FRNDO

FISSA

马德里

2

FRNDO

FISSA

马德里

克尔洛斯

FISSA

马德里

克尔洛斯

FISSA

马德里

克尔洛斯

FISSA

马德里

MRPHS

FISSA

马德里

FRNDO

马德里

一个

FRNDO

FRNDO

马德里

2

FRNDO

FRNDO

马德里

克尔洛斯

FRNDO

马德里

克尔洛斯

FRNDO

马德里

克尔洛斯

FRNDO

马德里

MRPHS

FRNDO

马德里

克尔洛斯

马德里

一个

FRNDO

克尔洛斯

马德里

2

FRNDO

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

MRPHS

克尔洛斯

马德里

MRPHS

耶路撒冷

一个

FRNDO

MRPHS

耶路撒冷

2

FRNDO

MRPHS

耶路撒冷

克尔洛斯

MRPHS

耶路撒冷

克尔洛斯

MRPHS

耶路撒冷

克尔洛斯

MRPHS

耶路撒冷

MRPHS

MRPHS

耶路撒冷

空值Step 1-J2:应用ON过滤,(JOIN 条件)

on筛选条件是sql的三个筛选条件(ON、WHERE、HAVING)中的第一个。对上一步中生成的虚拟表(VT1-J1)应用on筛选条件,并将满足ON筛选条件的行添加到虚拟表VT1-J2中。应用ON滤波后,生成的VT1-J2表如下:

c .客户id

c .城市

订单编号

o .客户id

FRNDO

马德里

一个

FRNDO

FRNDO

马德里

2

FRNDO

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

克尔洛斯

MRPHS

耶路撒冷

MRPHSStep 1-J3:添加外部列

只有使用外部连接时,才会出现这一步。对于外部连接(LEFT、RIGHT或FULL),可以将一个或两个表标记为保留表。作为保留表意味着您希望返回该表中的所有列,即使其中的数据不符合ON子句的筛选条件。LEFT OUTER JOIN将左边的表标记为保留表,RIGHTOUTER JOIN将右边的表标记为保留表,FULL OUTER JOIN将两个表都标记为保留表。步骤1-JBOY3乐队根据VT1-J2中的虚拟表,在保留表中添加不满足ON条件的列,而在未保留表中没有对应的列,因此标记为NULL。这个过程生成虚拟表VT1-JBOY3乐队。

c .客户id

c .城市

订单编号

o .客户id

FISSA

马德里

FRNDO

马德里

一个

FRNDO

FRNDO

马德里

2

FRNDO

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

克尔洛斯

MRPHS

耶路撒冷

MRPHS

如果FROM子句中有多个表操作,则从左到右处理sql,左边生成的临时表结果作为右边表的输入表。Step 2 WHERE 子句

其中过滤被应用于在先前步骤中产生的临时表,并且临时表VT2根据过滤条件产生。

注意:因为数据还没有分组,所以现在不能使用聚合运算——比如不能使用WHERE orderdate=MAX(orderdate)这样的句子。此外,不能使用在SELECT子句中创建的变量alias,因为SELECT子句还没有被处理——例如,不能写出这样的句子:SELECT YEAR(ORDER DATE)AS ORDER YEAR.订购2008年。

在C.city='Madrid '处应用此过滤器

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

c .客户id

c .城市

订单编号

o .客户id

FISSA

马德里

FRNDO

马德里

一个

FRNDO

FRNDO

马德里

2

FRNDO

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

克尔洛斯

在本例中,您需要在ON子句中使用ON c.customerid=o.customerid筛选。没有订单的客户在步骤1-J2中被过滤掉,但在步骤1-JBOY3乐队中作为外部列被添加回来。但是,由于您只想返回来自马德里的客户,因此需要在WHERE子句中过滤城市(其中c.city=' Madrid ')。如果您将其放入ON过滤器,不属于马德里的客户将被添加回Add External列。

这里需要解释一下ON和WHERE的区别。ON和WHERE的主要区别在于,ON在添加外部列之前进行筛选,而WHERE在添加外部列之后进行筛选。在已过滤的列上将被添加回1-JBOY3乐队。如果不需要添加外部列,那么这两个过滤器是一样的。Step 3 GROUP BY子句

该子句将对上一步中生成的临时表中的数据进行分组,每一行将被划分为仅一个组,以生成虚拟表VT3。VT3表包含VT2表中的所有数据和数据包标识符。

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

c .客户id组

c .客户id

c .城市

订单编号

o .客户id

FISSA

FISSA

马德里

FRNDO

FRNDO

马德里

一个

FRNDO

FRNDO

马德里

2

FRNDO

克尔洛斯

马德里

克尔洛斯

克尔洛斯

克尔洛斯

马德里

克尔洛斯

克尔洛斯

马德里

克尔洛斯

在sql返回的最终结果中,每个组必须只返回一行(除非被过滤掉)。因此,当在sql语句中使用GROUP BY时,在GROUP BY之后处理的子句(如SELECT和HAVING子句)只能使用出现在GROUP BY和聚合函数(如MAX、MIN、COUNT、AVG等)之后的列。)必须用于不出现在GROUP BY之后的列,以确保每个组只返回一行。Step 4 HAVING子句

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

当应用这个过滤器时:复制代码如下:具有COUNT(O.orderid) 3,生成的VT4表的内容如下:

c .客户id组

c .客户id

c .城市

订单编号

o .客户id

FISSA

FISSA

马德里

FRNDO

FRNDO

马德里

一个

FRNDO

FRNDO

马德里

2

FRNDO

值得注意的是,在这个查询中使用了COUNT(O.orderid)而不是COUNT(*)。当一个外部列被添加到该查询中时,COUNT方法将忽略空列,从而产生您不需要的结果。Step 5 SELECT 子句

虽然出现在sql语句的前面,但是SELECT是在第五步处理的,SELECT子句返回的表最终会返回给调用者。该子句包含三个子阶段:(5-1)评估表达式,(5-2)处理DISTINCT,以及(5-3)应用顶部过滤。

Step 5-1 计算表达式

SELECT子句中的表达式可以返回或操作上一个表中返回的基本列。如果此sql语句是一个聚合查询,在步骤3之后,您只能使用GROUP BY中的列,并且必须对不属于组集的列使用聚合操作。不属于FROM表中基本列的内容必须有一个别名,例如YEAR(orderdate)作为orderyear。

注意:在SELECT子句中创建的别名不能用于上一步,即使是在SELECT子句中。原因是sql的很多操作都是一次性操作,这里不介绍什么是一次性操作。因此,在SELECT子句中创建的别名只能在后面的子句中使用,如ORDER BY。示例:选择year (orderdate)作为订单年度.按订单年份排序。

在本例中:复制代码如下:选择c.customerid,count (o.orderid)作为num orders。结果,您将得到一个虚拟表VT5-1:

c .客户id

numorders

FIFSSA

0

FRNDO

2

Step 5-2:应用DISTINCT子句

如果在sql语句中使用DISTINCT,sql将删除重复的列并生成虚拟表VT5-2。

Step 5-3:应用TOP选项

TOP option是T-SQL提供的一个函数,用于指示显示多少行。根据ORDER BY子句定义的顺序,将查询指定数量的列。这个过程产生虚拟表VT5-3。

如上所述,这一步取决于ORDER BY定义的顺序来决定哪些列应该显示在前面。如果不按结果的顺序指定顺序,并且不使用WITH TIES子句,则每次返回的结果都可能不一致。

在我们的例子中,步骤5-3被省略了,因为我们没有使用TOP关键字。Step 6:ORDER BY子句

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

注意:这一步和上一步的区别在于,这一步返回的结果是游标,而不是表格。Sql是基于集合论的。集合不定义其行的顺序,它只是成员的逻辑集合,因此成员的顺序并不重要。带有ORDER BY子句的Sql返回一个对象,该对象以特定的顺序组织每一行。ANSI将这种对象称为光标。理解这一点对你理解sql很重要。以上步骤如图所示:

本书主要内容参考《微软sql Server 2008内部:T-SQL查询》中的内容。如果你想了解更多关于SQL查询的知识,可以找这本书。我这里有英文原版pdf,有需要可以找我要。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • 使用sql语句实现查询排序,顺序和倒序的区别,sql按倒序排序
  • 使用sql语句实现查询排序,顺序和倒序的区别,sql按倒序排序,使用SQL语句实现查询排序,顺序和倒序
  • 使用php连接mysql数据库,php连接数据库的方法
  • 使用php连接mysql数据库,php连接数据库的方法,一文详解PHP连接MySQL数据库的三种方式
  • 一篇文章带你入门sql编程语句,一篇文章带你入门sql编程题
  • 一篇文章带你入门sql编程语句,一篇文章带你入门sql编程题,一篇文章带你入门SQL编程
  • window无法启动mysql 1067,windows无法启动mysql57服务,错误1053
  • window无法启动mysql 1067,windows无法启动mysql57服务,错误1053,windows无法启动MySQL服务报错1067的解决方法
  • vb中adodb连接数据库,,VB语言使用ADO连接、操作SQLServer数据库教程
  • sql重复记录查询的几种方法有哪些,查询重复记录sql语句
  • sql重复记录查询的几种方法有哪些,查询重复记录sql语句,SQL重复记录查询的几种方法
  • sql语句的各个关键字的解析过程详细总结怎么写,sql语句的各个关键字的解析过程详细总结图
  • sql语句游标,sqlserver游标的使用
  • sql语句游标,sqlserver游标的使用,详解SQL游标的用法
  • sql语句比较时间大小,sql 时间比较大小
  • 留言与评论(共有 条评论)
       
    验证码: