我不確定你認爲這個ORDER BY
正在完成?即使您以合法的方式將做爲將ORDER BY
置於視圖中(例如,通過添加TOP
子句),如果您只是從視圖中進行選擇,例如SELECT * FROM dbo.TopUsersTest;
沒有ORDER BY
子句,SQL Server可以自由地以最有效的方式返回行,這不一定匹配您期望的順序。這是因爲ORDER BY
過載,因爲它試圖達到兩個目的:對結果進行排序並規定在TOP
中包含哪些行。在這種情況下,TOP
總會獲勝(儘管取決於選擇掃描數據的索引,您可能會發現您的訂單按預期工作 - 但這只是巧合)。
爲了達到您想要的效果,您需要將ORDER BY
子句添加到從視圖中提取數據的查詢,而不是視圖本身的代碼。
所以,你的視圖代碼應該僅僅是:
CREATE VIEW [dbo].[TopUsersTest]
AS
SELECT
u.[DisplayName], SUM(a.AnswerMark) AS Marks
FROM
dbo.Users_Questions AS uq
INNER JOIN [dbo].[Users] AS u
ON u.[UserID] = us.[UserID]
INNER JOIN [dbo].[Answers] AS a
ON a.[AnswerID] = uq.[AnswerID]
GROUP BY u.[DisplayName];
的ORDER BY
是沒有意義的,以便甚至不應該包括在內。
爲了說明,使用AdventureWorks2012,這裏有一個例子:
CREATE VIEW dbo.SillyView
AS
SELECT TOP 100 PERCENT
SalesOrderID, OrderDate, CustomerID , AccountNumber, TotalDue
FROM Sales.SalesOrderHeader
ORDER BY CustomerID;
GO
SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView;
結果:
SalesOrderID OrderDate CustomerID AccountNumber TotalDue
------------ ---------- ---------- -------------- ----------
43659 2005-07-01 29825 10-4020-000676 23153.2339
43660 2005-07-01 29672 10-4020-000117 1457.3288
43661 2005-07-01 29734 10-4020-000442 36865.8012
43662 2005-07-01 29994 10-4020-000227 32474.9324
43663 2005-07-01 29565 10-4020-000510 472.3108
而且你可以從該TOP
和ORDER BY
已經完全執行計劃見被SQL Server忽略和優化:
根本沒有TOP
運算符,也沒有排序。 SQL Server已完全將其優化。
現在,如果您將視圖更改爲ORDER BY SalesID
,那麼您恰好會得到該視圖的排序順序,但只有 - 正如前面提到的那樣 - 巧合。
但是,如果你改變你的外部查詢執行ORDER BY
你想:
SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView
ORDER BY CustomerID;
你得到的結果命令你想要的方式:
SalesOrderID OrderDate CustomerID AccountNumber TotalDue
------------ ---------- ---------- -------------- ----------
43793 2005-07-22 11000 10-4030-011000 3756.989
51522 2007-07-22 11000 10-4030-011000 2587.8769
57418 2007-11-04 11000 10-4030-011000 2770.2682
51493 2007-07-20 11001 10-4030-011001 2674.0227
43767 2005-07-18 11001 10-4030-011001 3729.364
而且計劃仍然優化掉了TOP
/ORDER BY
在視圖中,但添加了一種排序(以不小的代價,介意你),以顯示按CustomerID
排序的結果:
所以,故事的道德,不要把ORDER BY放在視圖中。將ORDER BY放入引用它們的查詢中。如果排序很昂貴,您可以考慮添加/更改索引來支持它。
[不幸''OFFSET'僅在SQL Server 2012上受支持](http://msdn.microsoft.com/zh-cn/library/ms188385(v=sql.110).aspx) – 2013-03-03 16:18:06
OFFSET是一個新的關鍵字在SQL 2012 – Phil 2013-03-03 16:18:07
視圖不能使用ORDER BY子句進行排序。您需要將ORDER BY子句放入任何引用該視圖的查詢中。爲了在客戶端應用程序中顯示查詢的結果,視圖和表中的行是無序的。 – sqlvogel 2013-03-03 16:41:10