前言

数据库的查询执行,毋庸置疑是程序员必备技能之一,然而数据库查询执行的过程绚烂多彩,却是很少被人了解,今天哥哥要带你装逼带你飞,深入一下这sql查询的来龙去脉,为查询的性能优化处理打个基础,或许面试你也会遇到,预防不跪还是看看吧。

这篇博客,摒弃查询优化性能,作为其基础,只针对查询流程讲解剖析。

本片博客阐述的过程为

1、上一个标识过的sql语句,展示查询执行的流程

2、上一个流程图

3、做一个例子逐步深入分析,帮助理解

4、做一个装逼的总结

sql查询语句的处理步骤,代码清单

--查询组合字段
(5)select (5-2) distinct(5-3) top(<top_specification>)(5-1)<select_list>
--连表
(1)from (1-J)<left_table><join_type> join <right_table> on <on_predicate>
(1-A)<left_table><apply_type> apply <right_table_expression> as <alias>
(1-P)<left_table> pivot (<pivot_specification>) as <alias>
(1-U)<left_table> unpivot (<unpivot_specification>) as <alias>
--查询条件
(2)where <where_pridicate>
--分组
(3)group by <group_by_specification>
--分组条件
(4)having<having_predicate>
--排序
(6)order by<order_by_list>

说明:

1、顺序为有1-6,6个大步骤,然后细分,5-1,5-2,5-3,由小变大顺序,1-J,1-A,1-P,1-U,为并行次序。如果不够明白,接下来我在来个流程图看看。

2、执行过程中也会相应的产生多个虚拟表(下面会有提到),以配合最终的正确查询。

sql查询语句的处理步骤,流程图

实例准备,创建表,插入数据,写要分析的实例查询语句

1、首先创建2各表

2、创建两个表,并插入表数据,脚本如下

USE [test]
GO
/****** Object: Table [dbo].[Member] Script Date: 2014/12/22 14:05:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Member](
[id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](30) NULL,
[phone] [varchar](15) NULL,
CONSTRAINT [PK_MEMBER] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[Order] Script Date: 2014/12/22 14:05:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Order](
[id] [int] IDENTITY(1,1) NOT NULL,
[member_id] [int] NULL,
[status] [int] NULL,
[createTime] [datetime] NULL,
CONSTRAINT [PK_ORDER] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO
SET IDENTITY_INSERT [dbo].[Member] ON GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (1, N'张龙豪', N'')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (2, N'Jim', N'')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (3, N'Tom', N'')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (4, N'Lulu', N'')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (5, N'Jick', N'')
GO
SET IDENTITY_INSERT [dbo].[Member] OFF
GO
SET IDENTITY_INSERT [dbo].[Order] ON GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (1, 1, 3, CAST(0x0000A40900B3BBFB AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (2, 2, 1, CAST(0x0000A40900B3CEF2 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (3, 3, 4, CAST(0x0000A40900B3D2D0 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (4, 4, 0, CAST(0x0000A40900B3D660 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (5, 5, 1, CAST(0x0000A40900B3D9B9 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (6, 6, 2, CAST(0x0000A40900B3DFEA AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (7, NULL, 0, CAST(0x0000A40900E34971 AS DateTime))
GO
SET IDENTITY_INSERT [dbo].[Order] OFF
GO
ALTER TABLE [dbo].[Order] ADD DEFAULT (getdate()) FOR [createTime]
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member', @level2type=N'COLUMN',@level2name=N'id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'姓名' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member', @level2type=N'COLUMN',@level2name=N'Name'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'电话' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member', @level2type=N'COLUMN',@level2name=N'phone'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'会员表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'会员编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'member_id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单状态' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'status'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'下单日期' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'createTime'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order'
GO

3、编写咱们要解析的查询语句,即本篇要查询的实例语句。

select top(4)  status , max(m.id) as maxMemberID
from [dbo].[Member] as m right outer join [dbo].[Order] as o
on m.id=o.member_id
where m.id>0
group by status
having status>=0
order by maxMemberID asc

实例语句分步骤分析

第一步,从from开始。

1.1、加载左表

from [dbo].[Member] as m 

查询结果:member表中的所有数据

1.2、这里应该是 right outer join ,但是这里在sql中被定义分解为2个步骤,即join ,right outer join 。表达式关键字从左到右,依次执行。

join [dbo].[Order] as o 

查询结果:存入虚拟表vt1,为两个表的笛卡尔集合。这里你或许不明白什么叫笛卡尔集合,我打个比方给说说,还望不要嫌弃,就是小朋友握手问题,A班里有3个学生(看作一个表的三条数据),B班里有2个学生(看作另外一个表的2条数据).B班小朋友跟A班小朋友搞联欢晚会,首先要每个人都要确保跟另外一个班的同学我一下手,那么交叉出来的集合就是(2*3=6)有6条不同的轨迹。这个轨迹的集合就是笛卡尔集合。如果你还不明白,我再说下,就是m(5条数据)表中的第一条数据跟o(7条数据)表中的所有数据握下手,有7条,然后依次类推共有35条不同的数据。这里的null值也是要加进来的。

1.3、on 筛选器

on m.id=o.member_id 

查询结果:从上一步的笛卡尔集合35条数据中删除掉不匹配的行,就得到啦5条数据,存入虚拟表Vt2

1.4、添加外部行(outer row)

right outer join [dbo].[Order] as o 

查询结果为:右表(order)作为保留表,把剩余的数据重新添加到上一步的虚拟表中vt2,生成虚拟表vt3.

第二部,进入where阶段

where m.id>0

查询结果:存入虚拟表vt4,为筛选的条件为true的结果集,这里加入一个记忆点,就是,where的筛选删除为永久的,而on的筛选删除为暂时的,因为on筛选过后,有可能会经过outer添加外部行,重新把数据加载回来,而where则不能。

第三部,group by分组

group by status

查询结果:存入vt5,以status列的数值开始分组,即status列,值一样的分为一组,这里的两个null在三值逻辑中被视为true。三值逻辑:true,false,null。此三值,null为未知,是数据的逻辑特色,有的地方两个null相等为ture,在有些地方则为false。这个你百度下看看有很多讲解。

 第四步,having筛选器

having status>=0 

查询结果:筛选分好组的组数据,把不满足条件的删除掉

第五步,select查询挑拣计算列

5.1、计算表达式

select status , max(m.id)

查询结果:从分过组的数据中计算各个组中的最大m.id,列出要筛选显示的列。

5.2、distinct过滤重复

5.3、top 结合order by 筛选 多少行,但这里的数据没有排序只是把多少行数据列出来而已。

第六部,order by 排序显示。

蛋疼的总结,装逼是有依据的

本篇博客参考:《Microsoft SQL Server 2008技术内幕:T-SQL查询》,感谢阅读,(C#).NET技术分享QQ群: 232458226,欢迎加入。

T-sql语句查询执行顺序的更多相关文章

  1. sql语句查询执行顺序

    http://blog.csdn.net/bitcarmanlee/article/details/51004767

  2. SQL语句的执行顺序和效率

    今天上午在开发的过程中,突然遇到一个问题,需要了解SQL语句的执行顺序才能继续,上网上查了一下相关的资料,现整理如下:一.sql语句的执行步骤: 1)语法分析,分析语句的语法是否符合规范,衡量语句中各 ...

  3. SQL语句的执行顺序

    一.sql语句的执行顺序 (8)SELECT (9) DISTINCT (11) <TOP_specification> <select_list> (1) FROM < ...

  4. SQL SERVER 一个SQL语句的执行顺序

    一个SQL 语句的执行顺序 1.From (告诉程序 来自哪张表  如果是表表达式 依旧是如此顺序) 2.Where(条件筛选  谓词筛选 ) 3.Group by(分组) 4.Having(分组   ...

  5. mysql 中sql语句的执行顺序

    今天突然想起来,之前面试一个很牛逼的公司(soho)的时候,一个美眉面试官,面试的时候问到了很多之前都没有意识到的问题,回想起来那美眉看着年纪不大,技术那是真666啊.好了说一下人家问的这个有关mys ...

  6. day57-mysql-五种约束和sql语句逻辑执行顺序

    二.sql语句逻辑执行顺序 () SELECT () DISTINCT <select_list> 去重复 () FROM <left_table> () <join_t ...

  7. [转载]T-SQL(Oracle)语句查询执行顺序

    原文链接:http://blog.sina.com.cn/s/blog_61c006ea0100mlgq.html sql语法的分析是从右到左,where子句中的条件书写顺序,基本上对sql性能没有影 ...

  8. MySQL——sql语句的执行顺序

    #核心知识点: 书写顺序:where——>group by——>having——>order by——>limit 许多时候在书写一些复杂的sql语句的时候,尤其是在渐进式推导 ...

  9. SQL server T-sql语句查询执行顺序

    前言 数据库的查询执行,毋庸置疑是程序员必备的技能之一,然而数据库查询执行的过程绚烂多彩,却是很少被人了解,今天我们来深入了解下sql查询的来龙去脉,为查询的性能优化打个基础 这篇博客,摒弃查询优化性 ...

随机推荐

  1. Tomcat shutdown执行后无法退出进程问题排查及解决

    问题定位及排查 上周无意中调试程序在Linux上ps -ef|grep tomcat发现有许多tomcat的进程,当时因为没有影响系统运行就没当回事.而且我内心总觉得这可能是tomcat像nginx一 ...

  2. 结合Jexus + Kestrel 部署 asp.net core 生产环境

    ASP.NET Core 是微软的全新的框架.这一框架的目标 ︰ 跨平台 针对云应用优化 解除 System.Web 的依赖. 获得下面三个方面的优势,你可以把它认为是一个C# 版本的NodeJS: ...

  3. HTML 事件(二) 事件的注册与注销

    本篇主要介绍HTML元素事件的注册.注销的方式. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流.事件委托 4. ...

  4. Python-Jenkins API使用 —— 在后端代码中操控Jenkins

    最近在工作中需要用到在后台代码中触发Jenkins任务的构建,于是想到Jenkins是否有一些已经封装好的API类库提供,用于处理跟Jenkins相关的操作.下面就简单介绍下我的发现. Linux C ...

  5. 《Django By Example》第三章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第三章滚烫出炉,大家请不要吐槽文中 ...

  6. 【翻译】Awesome R资源大全中文版来了,全球最火的R工具包一网打尽,超过300+工具,还在等什么?

    0.前言 虽然很早就知道R被微软收购,也很早知道R在统计分析处理方面很强大,开始一直没有行动过...直到 直到12月初在微软技术大会,看到我软的工程师演示R的使用,我就震惊了,然后最近在网上到处了解和 ...

  7. zookeeper源码分析之二客户端启动

    ZooKeeper Client Library提供了丰富直观的API供用户程序使用,下面是一些常用的API: create(path, data, flags): 创建一个ZNode, path是其 ...

  8. Windos环境用Nginx配置反向代理和负载均衡

    Windos环境用Nginx配置反向代理和负载均衡 引言:在前后端分离架构下,难免会遇到跨域问题.目前的解决方案大致有JSONP,反向代理,CORS这三种方式.JSONP兼容性良好,最大的缺点是只支持 ...

  9. class-dump 反编译私有的库和应用

    一.下载并安装class-dump 下载class-dump-3.5.dmg  点击下载 下载完成以后双击.dmg的文件,将里面的class-dump拷贝到/usr/local/bin 设置权限chm ...

  10. SCNU ACM 2016新生赛决赛 解题报告

    新生初赛题目.解题思路.参考代码一览 A. 拒绝虐狗 Problem Description CZJ 去排队打饭的时候看到前面有几对情侣秀恩爱,作为单身狗的 CZJ 表示很难受. 现在给出一个字符串代 ...