Saya tidak yakin apa yang Anda pikirkan ORDER BY
adalah mencapai? Bahkan jika Anda melakukannya masukkan ORDER BY
dalam tampilan secara legal (misalnya dengan menambahkan TOP
klausa), jika Anda hanya memilih dari tampilan, mis. SELECT * FROM dbo.TopUsersTest;
tanpa ORDER BY
klausa, SQL Server bebas untuk mengembalikan baris dengan cara yang paling efisien, yang belum tentu cocok dengan urutan yang Anda harapkan. Ini karena ORDER BY
kelebihan beban, karena mencoba melayani dua tujuan:untuk mengurutkan hasil dan untuk menentukan baris mana yang akan disertakan dalam TOP
. Dalam hal ini, TOP
selalu menang (meskipun tergantung pada indeks yang dipilih untuk memindai data, Anda mungkin mengamati bahwa pesanan Anda berfungsi seperti yang diharapkan - tetapi ini hanya kebetulan).
Untuk mencapai apa yang Anda inginkan, Anda perlu menambahkan ORDER BY
klausa ke kueri yang menarik data dari tampilan, bukan ke kode tampilan itu sendiri.
Jadi kode tampilan Anda seharusnya:
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
tidak ada artinya sehingga tidak boleh disertakan.
Sebagai ilustrasi, menggunakan AdventureWorks2012, berikut adalah contohnya:
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;
Hasil:
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
Dan Anda dapat melihat dari rencana eksekusi bahwa TOP
dan ORDER BY
telah benar-benar diabaikan dan dioptimalkan oleh SQL Server:
Tidak ada TOP
operator sama sekali, dan tidak ada semacam. SQL Server telah mengoptimalkannya sepenuhnya.
Sekarang, jika Anda mengubah tampilan untuk mengatakan ORDER BY SalesID
, Anda kemudian akan mendapatkan urutan yang dinyatakan oleh tampilan, tetapi hanya - seperti yang disebutkan sebelumnya - secara kebetulan.
Tetapi jika Anda mengubah kueri luar Anda untuk melakukan ORDER BY
Anda inginkan:
SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView
ORDER BY CustomerID;
Anda mendapatkan hasil yang dipesan seperti yang Anda inginkan:
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
Dan paket tersebut masih mengoptimalkan TOP
/ORDER BY
dalam tampilan, tetapi semacam ditambahkan (tanpa biaya kecil, ingatlah) untuk menyajikan hasil yang dipesan oleh CustomerID
:
Jadi, moral dari cerita ini, jangan menempatkan ORDER BY dalam tampilan. Masukkan ORDER BY dalam kueri yang merujuknya. Dan jika penyortiran mahal, Anda dapat mempertimbangkan untuk menambahkan/mengubah indeks untuk mendukungnya.