i漂泊

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 4700|回复: 0

SELECT语句逻辑执行顺序 你知道吗?

[复制链接]
TA的礼物信息
  • 收到:0
  • 送出:2
发表于 2014-5-10 22:40:20 | 显示全部楼层 |阅读模式
引言
  这不是一个什么多深的技术问题,多么牛叉的编程能力。这跟一个人的开发能力也没有非常必然的直接关系,但是知道这些会对你的SQL编写,排忧及优化上会有很大的帮助。它不是一个复杂的知识点,但是一个非常基础的SQL根基。不了解这些,你一直用普通水泥盖房子;掌握这些,你是在用高等水泥盖房子。
  然而,就是这么一个小小的知识点,大家可以去调查一下周围的同事朋友,没准你会得到一个“惊喜”。
  由于这篇文章是突然有感而写,下面随手编写的SQL语句没有经过测试。
  看下面的几段SQL语句:
  1. SELECT ID,COUNT(ID) AS TOTAL

  2. FROM STUDENT

  3. GROUP BY ID

  4. HAVING TOTAL>2
复制代码
  1. SELECT ID,COUNT(ID) AS TOTAL

  2. FROM STUDENT

  3. GROUP BY ID

  4. ORDER BY TOTAL
复制代码
  1. SELECT FIRSTNAME+' '+LASTNAME AS NAME, COUNT(*) AS COUNT

  2. FROM STUDENT

  3. 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语句的实际物理执行顺序可能会由于查询处理器的不同而与这个顺序有所出入。

 几个示例

  示例一
  1. SELECT ID,COUNT(ID) AS TOTAL

  2. FROM STUDENT

  3. GROUP BY ID

  4. 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的。
  示例二
  1. SELECT ID,COUNT(ID) AS TOTAL

  2. FROM STUDENT

  3. GROUP BY ID

  4. 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)呢?
  1. SELECT ID,COUNT(ID) AS TOTAL

  2. FROM STUDENT

  3. GROUP BY ID

  4. 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。
  示例三
  1. SELECT FIRSTNAME+' '+LASTNAME AS NAME, COUNT(*) AS COUNT

  2. FROM STUDENT

  3. GROUP BY NAME
复制代码
实际执行顺序:
  1. FROM STUDENT

  2. GROUP BY NAME

  3. SELECT FIRSTNAME+' '+LASTNAME AS NAME,COUNT(*) AS COUNT
复制代码
很明显,执行GROUP BY NAME时别名NAME还没有创建,因此它是不能执行成功的。
回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

QQ|小黑屋|手机版|IPiaoBo Inc. ( 渝ICP备17002826号 )

GMT+8, 2024-3-29 04:02 , Processed in 0.087561 second(s), 43 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表