Ответ 1
Я не уверен, что вы думаете об этом 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 в запросы, ссылающиеся на них. И если сортировка стоит дорого, вы можете подумать о добавлении/изменении индекса для его поддержки.