我不确定你认为这个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