数据库学习笔记(1):SELECT 各子句的执行顺序

来源:互联网 发布:绑定域名和空间 编辑:程序博客网 时间:2024/06/16 11:35
最近在学习数据库的相关知识,想和大家分享一下学习后的相关笔记。 
   当SELECT语句被DBMS执行时,其子句会按照固定的先后顺序执行: 
   (1)FROM  子句。 
   (2)WHERE 子句。 
   (3)GROUP BY 子句。 
   (4)HAVING 子句。 
   (5)SELECT 子句。 
   (6)ORDER BY 子句。 

   基本的工作原理:FROM子句先被执行,通过FROM子句获得一个虚拟表,然后通过WHERE子句从虚拟表中获取满足条件的记录,生成新的虚拟表。将新虚拟表中的记录通过GROUP BY子句分组后得到更新的虚拟表,而后HAVING子句在最新的虚拟表中筛选出满足条件的记录组成另外一个虚拟表中,SELECT子句会将指定的列提取出来组成更新的虚拟表,最后ORDER BY子句对其进行排序得出最终的虚拟表。通常这个最终的虚拟表被称为查询结果集。


另一篇

引言

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

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

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

  看下面的几段SQL语句:

1
2
3
4
5
6
7
SELECTID,COUNT(ID)ASTOTAL
 
FROMSTUDENT
 
GROUPBY ID
 
HAVINGTOTAL>2
1
2
3
4
5
6
7
SELECTID,COUNT(ID)ASTOTAL
 
FROMSTUDENT
 
GROUPBY ID
 
ORDERBY TOTAL
1
2
3
4
5
SELECTFIRSTNAME+' '+LASTNAMEASNAME,COUNT(*)ASCOUNT
 
FROMSTUDENT
 
GROUPBY 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语句的实际物理执行顺序可能会由于查询处理器的不同而与这个顺序有所出入。

 几个示例

  示例一

1
2
3
4
5
6
7
SELECTID,COUNT(ID)ASTOTAL
 
FROMSTUDENT
 
GROUPBY ID
 
HAVINGTOTAL>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的。

  示例二

1
2
3
4
5
6
7
SELECTID,COUNT(ID)ASTOTAL
 
FROMSTUDENT
 
GROUPBY ID
 
ORDERBY 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)呢?

1
2
3
4
5
6
7
SELECTID,COUNT(ID)ASTOTAL
 
FROMSTUDENT
 
GROUPBY ID
 
ORDERBY 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。

  示例三

1
2
3
4
5
SELECTFIRSTNAME+' '+LASTNAMEASNAME,COUNT(*)ASCOUNT
 
FROMSTUDENT
 
GROUPBY NAME

  实际执行顺序:

1
2
3
4
5
FROMSTUDENT
 
GROUPBY NAME
 
SELECTFIRSTNAME+' '+LASTNAMEASNAME,COUNT(*)ASCOUNT

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

 总结

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