SQL Server 查询处理中的各个阶段(SQL执行顺序)示例_MsSql

在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是最后被处理。

每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只是最后一步生成的表才会返回 给调用者。如果没有在查询中指定某一子句,将跳过相应的步骤。下面是对应用于SQL server 2000和SQL Server 2005的各个逻辑步骤的简单描述。

复制代码 代码如下:

(8)SELECT (9)DISTINCT  (11)<Top Num> <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)WITH <CUBE | RollUP>
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>

逻辑查询处理阶段简介
1.FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交叉联接),生成虚拟表VT1
2.ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2。
3.OUTER(JOIN):如 果指定了OUTER JOIN(相对于CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把两个表都标记为保留表)中未找到匹配的行将作为外部行添加到 VT2,生成VT3.如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表为止。
4.WHERE:对VT3应用WHERE筛选器。只有使<where_condition>为true的行才被插入VT4.
5.GROUP BY:按GROUP BY子句中的列列表对VT4中的行分组,生成VT5.
6.CUBE|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6.
7.HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.
8.SELECT:处理SELECT列表,处理各种聚积函数,并产生VT8.
9.DISTINCT:将重复的行从VT8中移除,产生VT9.
10.ORDER BY:将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10).
11.TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回调用者。
注:步骤10,按ORDER BY子句中的列列表排序上步返回的行,返回游标VC10.这一步是第一步也是唯一一步可以使用SELECT列表中的列别名的步骤。这一步不同于其它步骤的 是,它不返回有效的表,而是返回一个游标。SQL是基于集合理论的。集合不会预先对它的行排序,它只是成员的逻辑集合,成员的顺序无关紧要。对表进行排序 的查询可以返回一个对象,包含按特定物理顺序组织的行。ANSI把这种对象称为游标。理解这一步是正确理解SQL的基础。

因为这一步不返回表(而是返回游标),使用了ORDER BY子句的查询不能用作表表达式。表表达式包括:视图、内联表值函数、子查询、派生表和共用表达式。它的结果必须返回给期望得到物理记录的客户端应用程序。例如,下面的派生表查询无效,并产生一个错误:

复制代码 代码如下:

select *
from(select orderid,customerid from orders order by orderid)
as d

下面的视图也会产生错误

复制代码 代码如下:

create view my_view
as
select *
from orders
order by orderid

错误信息: Msg 1033, Level 15, State 1, Procedure my_viewasselect, Line 2The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries,and common table expressions, unless TOP or FOR XML is also specified.       在SQL中,表表达式中不允许使用带有ORDER BY子句的查询,而在T—SQL中却有一个例外(应用TOP选项)。
所以要记住,不要为表中的行假设任何特定的顺序。换句话说,除非你确定要有序行,否则不要指定ORDER BY 子句。排序是需要成本的,SQL Server需要执行有序索引扫描或使用排序运行符。

推荐一段SQL代码:行列转置

复制代码 代码如下:

/*问题:假设有张学生成绩表(tb)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
想变成(得到如下结果):
姓名 语文 数学 物理
---- ---- ---- ----
李四 74   84   94
张三 74   83   93
-------------------
*/
create table tb(姓名 varchar(10),课程 varchar(10),分数 int)
insert into tb values('张三' , '语文' , 74)
insert into tb values('张三' , '数学' , 83)
insert into tb values('张三' , '物理' , 93)
insert into tb values('李四' , '语文' , 74)
insert into tb values('李四' , '数学' , 84)
insert into tb values('李四' , '物理' , 94)
go
--SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)
select 姓名 as 姓名 ,
  max(case 课程 when '语文' then 分数 else 0 end) 语文,
  max(case 课程 when '数学' then 分数 else 0 end) 数学,
  max(case 课程 when '物理' then 分数 else 0 end) 物理
from tb
group by 姓名

时间: 2024-09-23 06:27:35

SQL Server 查询处理中的各个阶段(SQL执行顺序)示例_MsSql的相关文章

sql-【SQL求助】用SQL Server查询语句中,IN 的使用问题。

问题描述 [SQL求助]用SQL Server查询语句中,IN 的使用问题. 我想查询一辆车在一个月内的记录.于是编写了如下代码: select * from 北京车辆能耗数据.dbo.北京朝批商贸股份有限公司 where ( [列 0] in ('京AC3537') and CAST ([列 2] as datetime)>'2013/11/1 00:00:00' and CAST ([列 2] as datetime)<'2013/12/1 00:00:00' ) order by CAS

Sql Server 查询性能优化之走出索引的误区分析_MsSql

据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是,或者干脆把整个查询SQL直接发给DBA,让DBA直接帮忙优化了,所以造成的状况就是开发人员对于索引的理解.认识很局限,以下就把我个人对于索引的理解及浅薄认识和大家分享下,希望能解除一些大家的疑惑,一起走出索引的误区 误区1.在表上建立了索引,在查询时用到了索引的列,索引就一定会生效 首先明确下这样的

SQL Server 查询数据库中所有表数据条数

如果是要得到数据库中所有表的条数呢?我们来看几种最常见的方式: --方法一  代码如下 复制代码 select b.name as tablename , c.row_count as datacount from sys.indexes a , sys.objects b , sys.dm_db_partition_stats c where a.[object_id] = b.[object_id] AND b.[object_id] = c.[object_id] AND a.index_

Sql Server查询性能优化之不可小觑的书签查找介绍_MsSql

小小程序猿SQL Server认知的成长 1.没毕业或工作没多久,只知道有数据库.SQL这么个东东,浑然分不清SQL和Sql Server Oracle.MySql的关系,通常认为SQL就是SQL Server 2.工作好几年了,也写过不少SQL,却浑然不知道索引为何物,只知道数据库有索引这么个东西,分不清聚集索引和非聚集索引,只知道查询慢了建个索引查询就快了,到头来索引也建了不少,查询也确实快了,偶然问之:汝建之索引为何类型?答曰:... 3.终于受到刺激开始奋发图强,买书,gg查资料终于知道

SQL Server 查询数据库中所有的表名及行数

SELECT a.NAME ,b.rows FROM sysobjects AS a INNER JOIN sysindexes AS b ON a.id = b.id WHERE (a.type = 'u') AND ( b.indid IN ( 0 ,1 ) ) ORDER BY a.NAME ,b.rows DESC 作者:jiankunking 出处:http://blog.csdn.net/jiankunking

教你如何看懂SQL Server查询计划_MsSql

对于SQL Server的优化来说,优化查询可能是很常见的事情.由于数据库的优化,本身也是一个涉及面比较的广的话题,因此本文只谈优化查询时如何看懂SQL Server查询计划.毕竟我对SQL Server的认识有限,如有错误,也恳请您在发现后及时批评指正. 首先,打开[SQL Server Management Studio],输入一个查询语句看看SQL Server是如何显示查询计划的吧. 说明:本文所演示的数据库,是我为一个演示程序专用准备的数据库,可以在此网页中下载. select v.O

教你如何看懂SQL Server查询计划

对于SQL Server的优化来说,优化查询可能是很常见的事情.由于数据库的优化,本身也是一个涉及面比较的广的话题,因此本文只谈优化查询时如何看懂SQL Server查询计划.毕竟我对SQL Server的认识有限,如有错误,也恳请您在发现后及时批评指正. 首先,打开[SQL Server Management Studio],输入一个查询语句看看SQL Server是如何显示查询计划的吧. 说明:本文所演示的数据库,是我为一个演示程序专用准备的数据库,可以在此网页中下载. select v.O

关于sql server查询语句的写法。

问题描述 关于sql server查询语句的写法. 怎样写一个查询语句select distinct ID from TrainTime order by ID select Station from TrainTime where S_No='1'order by ID select Stationfrom TrainTime where D_Time='-' order by ID 怎样把这3个查询语句写为一句啊,让查询查来的结果为这3列数据. 因为我想建一个表,为3列,列名为:列车车次.起

T-SQL命令在SQL Server查询中的运用

server 首先需要说明的是这篇文章的内容并不是如何调节SQL Server查询性能的(有关这方面的内容能写一本书),而是如何在SQL Server查询性能的调节中利用SET STATISTICS IO和SET STATISTICS TIME这二条被经常忽略的Transact-SQL命令的. 从表面上看,查询性能的调节是一件十分简单的事.从本质上讲,我们希望查询的运行速度能够尽可能地快,无论是将查询运行的时间从10分钟缩减为1分钟,还是将运行的时间从2秒钟缩短为1秒种,我们最终的目标都是减少运