Я не уверен, что вы думаете об этом 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/en-us/library/ms188385 (v = sql.110) .aspx) –
OFFSET - это новое ключевое слово в SQL 2012 – Phil
Просмотр не может быть отсортировано с предложением ORDER BY. Вы должны поместить предложение ORDER BY в любой запрос, который ссылается на представление. Результаты запросов упорядочиваются для отображения в клиентском приложении; строки в представлениях и таблицах неупорядочены. – sqlvogel