Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Criar uma visualização com a cláusula ORDER BY


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.