Não tenho certeza do que você acha deste
ORDER BY
está realizando? Mesmo que você faça coloque ORDER BY
na visualização de forma legal (por exemplo, adicionando um TOP
cláusula), se você apenas selecionar na exibição, por exemplo SELECT * FROM dbo.TopUsersTest;
sem um ORDER BY
cláusula, o SQL Server é livre para retornar as linhas da maneira mais eficiente, o que não corresponderá necessariamente à ordem que você espera. Isso ocorre porque ORDER BY
está sobrecarregado, pois tenta servir a dois propósitos:classificar os resultados e ditar quais linhas incluir em TOP
. Neste caso, TOP
sempre vence (embora, dependendo do índice escolhido para varrer os dados, você possa observar que seu pedido está funcionando conforme o esperado - mas isso é apenas uma coincidência). Para realizar o que deseja, você precisa adicionar seu
ORDER BY
cláusula para as consultas que extraem dados da visualização, não para o código da visualização em si. Portanto, seu código de visualização deve ser apenas:
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];
O
ORDER BY
não tem sentido, então nem deveria ser incluído. Para ilustrar, usando o AdventureWorks2012, aqui está um exemplo:
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;
Resultados:
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 você pode ver no plano de execução que o
TOP
e ORDER BY
foram absolutamente ignorados e otimizados pelo SQL Server:Não há
TOP
operador em tudo, e nenhum tipo. O SQL Server os otimizou completamente. Agora, se você alterar a visualização para dizer
ORDER BY SalesID
, você obterá a ordenação que a exibição indica, mas apenas - como mencionado antes - por coincidência. Mas se você alterar sua consulta externa para executar o
ORDER BY
você queria:SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView
ORDER BY CustomerID;
Você obtém os resultados ordenados da maneira que deseja:
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 o plano ainda otimizou o
TOP
/ORDER BY
na visualização, mas uma classificação é adicionada (sem um custo pequeno, lembre-se) para apresentar os resultados ordenados por CustomerID
:Então, moral da história, não coloque ORDER BY nas visualizações. Coloque ORDER BY nas consultas que os referenciam. E se a classificação for cara, você pode considerar adicionar/alterar um índice para suportá-la.