select語句執行順序

轉自:http://www.admin10000.com/document/4373.html

引言

  這不是一個什麼多深的技術問題,多麼牛叉的編程能力。這跟一個人的開發能力也沒有非常必然的直接關係,但是知道這些會對你的SQL編寫,排憂及優化上會有很大的幫助。它不是一個複雜的知識點,但是一個非常基礎的SQL根基。不瞭解這些,你一直用普通水泥蓋房子;掌握這些,你是在用高等水泥蓋房子。

  然而,就是這麼一個小小的知識點,大家可以去調查一下週圍的同事朋友,沒準你會得到一個“驚喜”。

  由於這篇文章是突然有感而寫,下面隨手編寫的SQL語句沒有經過測試。

  看下面的幾段SQL語句:

1
2
3
4
5
6
7
SELECT ID,COUNT(ID) AS TOTAL
 
FROM STUDENT
 
GROUP BY ID
 
HAVING TOTAL>2
1
2
3
4
5
6
7
SELECT ID,COUNT(ID) AS TOTAL
 
FROM STUDENT
 
GROUP BY ID
 
ORDER BY TOTAL
1
2
3
4
5
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語句的實際物理執行順序可能會由於查詢處理器的不同而與這個順序有所出入。

 幾個示例

  示例一

1
2
3
4
5
6
7
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的。

  示例二

1
2
3
4
5
6
7
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)呢?

1
2
3
4
5
6
7
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。

  示例三

1
2
3
4
5
SELECT FIRSTNAME+' '+LASTNAME AS NAME, COUNT(*) AS COUNT
 
FROM STUDENT
 
GROUP BY NAME

  實際執行順序:

1
2
3
4
5
FROM STUDENT
 
GROUP BY NAME
 
SELECT FIRSTNAME+' '+LASTNAME AS NAME,COUNT(*) AS COUNT

  很明顯,執行GROUP BY NAME時別名NAME還沒有創建,因此它是不能執行成功的。

 總結

  回憶起曾經隨意問過一些人這個問題,不管誰說不知道時我們都會故意嘲笑一翻,當然此嘲笑非彼嘲笑。但事實證明還是有一些人不會注意到這個知識點,在此貼出來只是做爲一個友好的提醒。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章