我們知道在SQL語句中,ORDER BY語句可以用來排序。但是在SQL Server中,如果我們在子查詢、視圖、內聯函數等數據庫對象中單獨使用ORDER BY語句是不允許的,來看下面的SQL語句:
SELECT * FROM ( SELECT [ID],[Code],[Name],[Age],[Sex],[Class] FROM [dbo].[Student] ORDER BY [ID] DESC ) AS T_Student
執行該語句,SQL Server會報錯,錯誤信息如下:
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
該錯誤信息明確地指出ORDER BY語句不能夠在子查詢、視圖、內聯函數等數據庫對象中使用,除非是用了TOP、OFFSET、FOR XML語句。
這個錯誤是微軟想讓開發者明白一個道理,那就是像子查詢、視圖、內聯函數等這種中間結果查詢,是不應該負責對查詢結果進行排序的,對查詢結果排序是最外層查詢才應該做的事情,而不是中間結果查詢該做的事。
那么為什么加了TOP、OFFSET、FOR XML語句后,子查詢、視圖、內聯函數等數據庫對象中就可以用ORDER BY語句了呢?那是因為這時ORDER BY語句只起到數據篩選的作用,並不是對查詢結果排序。舉個例子,如果我們要得到[Student]表中[ID]列最大的5條數據記錄,就可以在子查詢中將ORDER BY語句和TOP語句放在一起使用,如下所示:
SELECT * FROM ( SELECT TOP 5 [ID],[Code],[Name],[Age],[Sex],[Class] FROM [dbo].[Student] ORDER BY [ID] DESC ) AS T_Student
這個SQL語句是不會報錯的,執行結果如下:
所以我們可以看到[ID]列最大的5條數據記錄,就被查詢出來了。但是我們前面說了ORDER BY語句在子查詢、視圖、內聯函數等數據庫對象中只起到數據篩選的作用,所以如果我們真的想對[ID]列排序,應該在最外層查詢再使用ORDER BY語句(雖然上面截圖的查詢結果中,數據已經按照[ID]列的降序排列,但事實上SQL Server並不保證每次查詢結果肯定是按照[ID]列降序排列,你可以認為這只是一個巧合),如下所示:
SELECT * FROM ( SELECT TOP 5 [ID],[Code],[Name],[Age],[Sex],[Class] FROM [dbo].[Student] ORDER BY [ID] DESC ) AS T_Student ORDER BY [ID] DESC
所以真正起到對查詢結果進行排序的是最外層查詢的ORDER BY語句,而不是子查詢中的ORDER BY語句。