我不确定你认为这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 放在引用它们的查询中。如果排序很昂贵,您可能会考虑添加/更改索引以支持它。