1. 程式人生 > >DQL中的執行順序詳解

DQL中的執行順序詳解


引言


這不是一個什麼多深的技術問題,多麼牛叉的程式設計能力。這跟一個人的開發能力也沒有非常必然的直接關係,但是知道這些會對你的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還沒有建立,因此它是不能執行成功的。

總結


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