准备数据

Sql脚本如下,两张表,一张客户表Customers只包含customerid和city字段,一张订单表Orders包含orderid和customerid(关联Customers的customerid字段)

IF OBJECT_ID('dbo.Orders') IS NOT NULL DROP TABLE dbo.Orders;
IF OBJECT_ID('dbo.Customers') IS NOT NULL DROP TABLE dbo.Customers;
GO CREATE TABLE dbo.Customers
(
customerid CHAR(5) NOT NULL PRIMARY KEY,
city VARCHAR(10) NOT NULL
); CREATE TABLE dbo.Orders
(
orderid INT NOT NULL PRIMARY KEY,
customerid CHAR(5) NULL REFERENCES Customers(customerid)
);
GO INSERT INTO dbo.Customers(customerid, city) VALUES('FISSA', 'Madrid');
INSERT INTO dbo.Customers(customerid, city) VALUES('FRNDO', 'Madrid');
INSERT INTO dbo.Customers(customerid, city) VALUES('KRLOS', 'Madrid');
INSERT INTO dbo.Customers(customerid, city) VALUES('MRPHS', 'Zion'); INSERT INTO dbo.Orders(orderid, customerid) VALUES(1, 'FRNDO');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(2, 'FRNDO');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(3, 'KRLOS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(4, 'KRLOS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(5, 'KRLOS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(6, 'MRPHS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(7, NULL);

对于一条Sql语句(主要指的是查询语句)的执行顺序,很多开发人员并不是十分的了解,哪怕已经工作几年的所谓高级开发人员也是一样,对于他们来说,只关心最终得到的结果,并不关心中间的过程,那么了解SqlServer的语句执行过程到底有什么用处的?

1、如果不了解执行过程,下面的Sql语句你认为结果是一样的吗?

select * from Customers AS C
left join Orders AS O
On C.customerid=O.customerid
and C.customerid='FRNDO'
where city ='Madrid' select * from Customers AS C
left join Orders AS O
On C.customerid=O.customerid
where city ='Madrid'
and C.customerid='FRNDO'

如果你了解Sql的执行顺序,这个问题就不难解释了,只不过是On语句和Where语句谁先执行以及On和Where之间是否还有其它执行步骤?

2、下面这两条语句,第一个会提示列where语句中的myorder(select 中起的别名)无效,第二条是可以正常执行的,那问题来了,为什么order by语句中可以使用myorder列而where中就不可以呢?

select C.customerid,C.city,O.orderid as myorder
from Customers AS C
left join Orders AS O
On C.customerid=O.customerid
where myorder >3
order by myorder desc select C.customerid,C.city,O.orderid as myorder
from Customers AS C
left join Orders AS O
On C.customerid=O.customerid
where O.orderid >3
order by myorder desc

Sql语句逻辑执行顺序

一条常用的查询语句应当是包含了下面的几条命令

select distinct top 3  C.customerid, count(O.orderid) as orderCount
from Customers as C
left join Orders as O
ON C.customerid=O.customerid
where C.city='Madrid'
group by C.customerid
having count(O.orderid)>1
order by orderCount desc

1、From阶段

From阶段主要是标识数据来源,处理表运算符(join、apply,pivot等,本文只针对join讲解),以及各个子阶段(包括笛卡尔积、ON筛选器应用、添加外部行[只有外链接才有]);

1.1 join阶段   join分为cross join、inner join、[left join、right join,full join]

cross join只是简单的进行笛卡尔积,如上面的两张表cross join之后的结果如下图(左一);

inner join是在cross join的基础上加入了ON筛选条件,如图(左二和左三),只有ON(C.customerId=O.customerId)为Ture的才会返回

left join 是在 inner join的基础上添加了外部行,在ON阶段获取的数据基础上添加左表(Customer表)中的未满足ON筛选条件的所有行(未在ON阶段出现的),如图(左四)

2、Where 阶段

where 阶段就是对From阶段得到的虚拟表进行进一步的过滤和筛选,和Join中的ON筛选类似,只是比ON筛选器执行的晚,特别对于外链接来说,ON筛选和Where筛选中间还多了一步添加外部行,这里应该可以解释本文开篇提到的第一个问题了。

3、Group By

Group By 只是按照指定的列名对第二步(如果存在)Where阶段得到的虚拟表进行分组,每个分组只有一条数据,一般都是使用聚合函数来计算一些数据,比如上面例子中用按照CustomerId进行分组,用Count获取每个客户的订单数量,然后按照订单数量倒序去排名前三的客户。

4、Having

Having阶段是在第三步(如果存在)分组之后再一次进行过滤,也就是对Group By阶段得到的虚拟结果集进行进一步的筛选过滤,过程和ON、Where类似,只能用在Group BY 之后。

5、Select

Select 阶段则是针对第四步(如果存在)获取的虚拟表的基础上选择需要的列,也就是最终要返回的列,看到这里是不是明白了本文开篇提到的第二个问题,为什么Select中的别名不能再Wher阶段使用,因为Where早于Select,

Select又可以分为几个子阶段,包括(5.1计算表达式,5.2 Distinct,5.3 Top)

6、Order By

Order By 阶段是整个查询的最后阶段也就是根据指定的列名对Select阶段进行排序,这也就是为什么在Order By语句中可以用Select阶段起的别名的原因,不过Order By阶段和上面的5个阶段有个很大的区别,Order By阶段返回的数据集是游标,而上面的5个阶段生成的都是数据表,理解这点很重要,SqlServer的理论基础是集合论,集合中的行之间没有预先定义顺序,它只是成员之间的逻辑组合,成员之间的顺序无关紧要,而对于带有Order By的查询语句,是返回了一个按照特定的顺寻组成的一个对象,成为游标。

最后附上一张Sql语句的执行流程图(图片来源Sql08解密)

总结

不知不觉已经写了将近3个小时了,本文简单介绍SqlServer中个语句的执行过程,只有理解的个语句的执行过程,才能写出更加准确,更加高效的Sql命令。

SqlServer中Sql语句的逻辑执行顺序的更多相关文章

  1. sql中select语句的逻辑执行顺序

    下面是SELECT语句的逻辑执行顺序: FROMONJOINWHEREGROUP BYWITH CUBE or WITH ROLLUPHAVINGSELECTDISTINCTORDER BYTOP M ...

  2. SQLServer中SQL语句与可执行二进制语句

    SQLServer可以执行正常SQL语句也可以执行被转换的二进制语句,一般会用此方法进行数据库注入操作,骗过基本的字符过滤 --将二进制格式转为普通SQL语句 ) = 0x53454C45435420 ...

  3. SQL语句完整的执行顺序(02)

    这是对SQL语句完整的执行顺序(01)的补充: 数据库是mysql,使用的数据库表名称是my_student. 表的完整数据信息是: 完整语法是: Select [select选项] 字段列表[字段别 ...

  4. 单表:SQL语句关键字的执行顺序

    表和数据: -- 创建表 CREATE TABLE `person` ( `id` ) NOT NULL AUTO_INCREMENT, `name` ) NOT NULL, `age` ) ', ` ...

  5. 【SQL】SQL 中Select语句完整的执行顺序

    SQL Select语句完整的执行顺序: 1.from子句组装来自不同数据源的数据: 2.where子句基于指定的条件对记录行进行筛选: 3.group by子句将数据划分为多个分组: 4.使用聚集函 ...

  6. SQL语句完整的执行顺序(01)

    一.sql语句的执行步骤:  1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义.  2) 语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限.  3)视图转换,将涉 ...

  7. Oracle中Select语句完整的执行顺序

    oracle Select语句完整的执行顺序: .from 子句组装来自不同数据源的数据: .where 子句基于指定的条件对记录行进行筛选: .group by子句将数据划分为多个分组: .使用聚集 ...

  8. mysql 中sql语句关键字的书写顺序与执行顺序

    书写顺序: select -> from -> where -> group by -> having -> order by 执行顺序: from -> wher ...

  9. 转载《mysql 一》:mysql的select查询语句内在逻辑执行顺序

    原文:http://www.jellythink.com/archives/924 我的抱怨 我一个搞应用开发的,非要会数据库,这不是专门的数据库开发人员干的事么?话说,小公司也没有数 据库开发人员这 ...

随机推荐

  1. std::cout彩色输出

    Mac OS效果 Windows 效果 想写这个东西其实是因为最近要写个命令行的工具,但是有个问题是什么呢?就是传统的那个黑漆漆的窗口看起来很蛋疼.并且完全看不到重点,于是就想起 来这么一个东西.相对 ...

  2. 隐藏DLL

    先来推广一下QQ群:61618925.欢迎各位爱好编程的加入. 在外挂或者病毒中,经常需要隐藏掉自己注入的DLL,以免被发现.下面就是一个隐藏DLL的通用模块,用的时候只需要加入到相关模块中即可. 详 ...

  3. ASP.NET MVC SignalR(1):背景

    系列目录:ASP.NET MVC SignalR 关键词:HTTP.轮询.WebSocket.Server-Sent Events.长轮询.forever frame. 1. HTTP HTTP(Hy ...

  4. 软件工程 speedsnail 冲刺6

    2015-5-10 完成任务:学习了黑马android教学视频13.14.15集,记分功能: 遇到问题: 问题1 android native method not found 解决1 没有解决 明日 ...

  5. IOS屏幕布局

    1.iPad和iPhone的屏幕布局 在IB中,屏幕或控件的尺寸以点为单位.在视网膜技术中,1个点包括4个像素,而没有采用视网膜屏幕技术的还是1个点包括1个像素. 2.绝对布局和相对布局 3.使用Au ...

  6. 《第一行代码--Android》阅读笔记之广播

    广播接收器 1.注册方式 动态注册:在程序中注册,如在Activity里的onCreate()方法中注册 静态注册:在AndroidManifest.xml中注册   2.可接收哪些广播 接收系统消息 ...

  7. Log4net使用笔记

    Log4net使用笔记   编写人:CC阿爸 2013-10-29 近来在处理项目时候,想将系统的操作日志以文本的形式记录下来,方便对系统操作记录进行追踪. 经过在网上搜索部分解决方案,大致可以归纳如 ...

  8. silverlight嵌套html不能输入中文问题

    1.xaml <UserControl xmlns:SilverlightClient="clr-namespace:SilverlightClient" x:Class=& ...

  9. text-rendering 详解

    原文链接:http://www.feeldesignstudio.com/2013/05/text-rendering Text-rendering 属性是一个非标准属性,主要用来告诉渲染引擎(ren ...

  10. Mysql导入导出 改密命令总结(笔记三)

    一.从数据库导出数据 注意这些语句的执行是在在没进入mysql命令行之前,在mysql命令行不行 C:\Windows\system32>导出命令 而不是 Mysql>导出命令 1.导出整 ...