Non sono sicuro di cosa ne pensi questo ORDER BY
sta realizzando? Anche se lo fai inserisci ORDER BY
nella vista in modo legale (ad es. aggiungendo un TOP
clausola), se si seleziona dalla vista, ad es. SELECT * FROM dbo.TopUsersTest;
senza un ORDER BY
clausola, SQL Server è libero di restituire le righe nel modo più efficiente, che non corrisponderà necessariamente all'ordine previsto. Questo perché ORDER BY
è sovraccarico, in quanto cerca di servire a due scopi:ordinare i risultati e dettare quali righe includere in TOP
. In questo caso, TOP
vince sempre (anche se a seconda dell'indice scelto per scansionare i dati, potresti osservare che il tuo ordine funziona come previsto, ma questa è solo una coincidenza).
Per realizzare ciò che desideri, devi aggiungere il tuo ORDER BY
clausola alle query che estraggono i dati dalla vista, non al codice della vista stessa.
Quindi il tuo codice di visualizzazione dovrebbe essere solo:
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];
Il ORDER BY
non ha senso, quindi non dovrebbe nemmeno essere incluso.
Per illustrare, utilizzando AdventureWorks2012, ecco un esempio:
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;
Risultati:
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
E puoi vedere dal piano di esecuzione che il TOP
e ORDER BY
sono stati assolutamente ignorati e ottimizzati da SQL Server:
Non c'è nessun TOP
operatore a tutti e nessun ordinamento. SQL Server li ha ottimizzati completamente.
Ora, se cambi la visualizzazione per dire ORDER BY SalesID
, ti capiterà di ottenere l'ordine indicato nella visualizzazione, ma solo - come accennato in precedenza - per coincidenza.
Ma se modifichi la tua query esterna per eseguire ORDER BY
volevi:
SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView
ORDER BY CustomerID;
Ottieni i risultati ordinati nel modo desiderato:
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
E il piano ha ancora ottimizzato il TOP
/ORDER BY
nella vista, ma viene aggiunto un ordinamento (a costo zero, intendiamoci) per presentare i risultati ordinati per CustomerID
:
Quindi, morale della storia, non inserire ORDER BY nelle viste. Inserisci ORDER BY nelle query che li fanno riferimento. E se l'ordinamento è costoso, potresti considerare di aggiungere/modificare un indice per supportarlo.