欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

数据库中的SELECT语句逻辑执行顺序分析

程序员文章站 2024-03-01 16:05:16
引言   这不是一个什么多深的技术问题,多么牛叉的编程能力。这跟一个人的开发能力也没有非常必然的直接关系,但是知道这些会对你的sql编写,排忧及优化上会有很大的帮助。它不...

引言

  这不是一个什么多深的技术问题,多么牛叉的编程能力。这跟一个人的开发能力也没有非常必然的直接关系,但是知道这些会对你的sql编写,排忧及优化上会有很大的帮助。它不是一个复杂的知识点,但是一个非常基础的sql根基。不了解这些,你一直用普通水泥盖房子;掌握这些,你是在用高等水泥盖房子。

  然而,就是这么一个小小的知识点,大家可以去调查一下周围的同事朋友,没准你会得到一个“惊喜”。

  由于这篇文章是突然有感而写,下面随手编写的sql语句没有经过测试。

  看下面的几段sql语句:

复制代码 代码如下:
#1
select id,count(id) as total
 
from student
 
group by id
 
having total>2
#2
select id,count(id) as total
 
from student
 
group by id
 
order by total
#3
select firstname+' '+lastname as name, count(*) as count
 
from student
 
group by name

你觉得哪一个不能够成功执行?

下面是select语句的逻辑执行顺序:

1.from
2.on
3.join
4.where
5.group by
6.with cube or with rollup
7.having
8.select
9.distinct
10.order by
11.top
  microsoft指出,select语句的实际物理执行顺序可能会由于查询处理器的不同而与这个顺序有所出入。

几个示例

示例一:

复制代码 代码如下:

select id,count(id) as total
 
from student
 
group by id
 
having total>2

觉得这个sql语句眼熟吗?对,非常基础的分组查询。但它不能执行成功,因为having的执行顺序在select之上。

实际执行顺序如下:

1.from student
2.group by id
3.having total>2
4.select id,count(id) as total
  很明显,total是在最后一句select id,count(id) as total执行过后生成的新别名。因此,在having total>2执行时是不能识别total的。

示例二

复制代码 代码如下:

select id,count(id) as total
 
from student
 
group by id
 
order by total

这个的实际执行顺序是:

1.from student
2.group by id
3.select id,count(id) as total
4.order by total
  这一次没有任何问题,能够成功执行。如果把order by total换成order by count(id)呢?

复制代码 代码如下:

select id,count(id) as total
 
from student
 
group by id
 
order by count(id)

实际执行顺序:

1.from student
2.group by id
3.select id,count(id) as total
4.order by count(id)

  没错,它是能够成功执行的,看sql执行计划,它与上面order by total是一样的。order by 是在select后执行,因此可以用别名total。

示例三

复制代码 代码如下:

select firstname+' '+lastname as name, count(*) as count
 
from student
 
group by name

 实际执行顺序:

复制代码 代码如下:

from student
 
group by name
 
select firstname+' '+lastname as name,count(*) as count

很明显,执行group by name时别名name还没有创建,因此它是不能执行成功的。

总结

  回忆起曾经随意问过一些人这个问题,不管谁说不知道时我们都会故意嘲笑一翻,当然此嘲笑非彼嘲笑。但事实证明还是有一些人不会注意到这个知识点,在此贴出来只是做为一个友好的提醒。