【SQL】查询逻辑分析

我们先来看两个问题:

问题1:为什么上面的语句执行报错,下面的不报错

问题2:以下sql语句执行结果是否应该一致?

 那为什么会这样呢?这就牵涉到了SQL的逻辑查询处理流程

SQL逻辑查询处理

SQL查询分为逻辑处理和物理处理 ,本次我们重点介绍逻辑查询处理。在实践中,查询的实际物理处理和逻辑处理有很大不同。

在SQLServer中负责生成实际工作计划(执行计划)的组件是查询优化器,以何种顺序访问表、使用哪种访问方法、应用哪种联接算法都是由优化器决定。优化器会生成多个有效的执行计划,并从中选择一个开销最低的计划。

逻辑查询处理中的各个阶段都有着特定的顺序。

扫描二维码关注公众号,回复: 8638105 查看本文章

SQL不同于其它编程语言的最明显特性是处理代码的顺序。在大多数编程语言中,代码是按照编写顺序来处理的。

每个步骤都会产生一个虚拟表,该虚拟表作为下一个步骤的输入。只有最后一步生成的表才会返回给调用者。

逻辑处理阶段简介

FROMForm阶段标识出查询的来源表,处理表运算符。例如,在联接运行中涉及的阶段笛卡尔积、ON筛选器和添加外部行(OUTER JOIN)。

笛卡尔积:对FROM涉及的两个表执行笛卡尔积(交叉连接),生成虚拟表VT1

ON:对VT1应用ON筛选器,只有满足条件的行才被插入VT2

OUTER JOIN:保留表中未找到的行添加到VT2,生成VT3

WHERE:只有满足WHERE条件的行才被插入到VT4

GROUP BY:按照GROUP BY子句中指定的列名列表,对VT4进行分组,生成VT5。每个分组只有一个结果行。

HAVING:对VT5应用HAVING筛选器,只有满足条件的才插入VT6

SELECT:处理SELECT列表,生成VT7

计算表达式:计算SELECT列表中的表达式,生成VT8

DISTINCT:将删除VT8中重复行,产生VT9

TOP:根据ORDER BY子句定义的逻辑排序,从VC9中选择指定数量或百分比的行,生成表VT10

ORDER BY:根据ORDER BY子句中指定的列名列表,对V10进行排序,返回游标VC11,也是唯一可以使用选SELECT列表中别名的步骤

逻辑查询处理阶段详解

示例:
select s.Sdept,sc.subject,sum(sc.score) allScore,avg(sc.score) avgScore		
from Score sc
inner join Student s
on sc.Sno11=s.Sno
where s.Sage>=20
group by s.Sdept,sc.subject
having avg(sc.score)>70
order by avgScore desc

因此,才导致了上述查询的报错和不一致问题,在编写SQL语句的时候要谨记它的处理流程。

发布了62 篇原创文章 · 获赞 14 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Yanzudada/article/details/102861462