Не съм сигурен какво мислите за това 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 в заявките, които ги препращат. И ако сортирането е скъпо, може да помислите за добавяне/промяна на индекс, за да го поддържате.