SELECT語句邏輯執行順序 你知道嗎?

DePaul發表於2014-05-08

 引言

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

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

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

  看下面的幾段SQL語句:

SELECT ID,COUNT(ID) AS TOTAL

FROM STUDENT

GROUP BY ID

HAVING TOTAL>2
SELECT ID,COUNT(ID) AS TOTAL

FROM STUDENT

GROUP BY ID

ORDER BY TOTAL
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還沒有建立,因此它是不能執行成功的。

 總結

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

相關文章