No estoy seguro de lo que piensas de este ORDER BY
esta logrando? Incluso si haces poner ORDER BY
en la vista de forma legal (por ejemplo, agregando un TOP
cláusula), si solo selecciona de la vista, p. SELECT * FROM dbo.TopUsersTest;
sin ORDER BY
cláusula, SQL Server es libre de devolver las filas de la manera más eficiente, que no necesariamente coincidirá con el orden que espera. Esto se debe a que ORDER BY
está sobrecargado, ya que intenta cumplir dos propósitos:ordenar los resultados y dictar qué filas incluir en TOP
. En este caso, TOP
siempre gana (aunque dependiendo del índice elegido para escanear los datos, es posible que observe que su pedido funciona como se esperaba, pero esto es solo una coincidencia).
Para lograr lo que desea, debe agregar su ORDER BY
cláusula a las consultas que extraen datos de la vista, no al código de la vista en sí.
Entonces su código de vista debería ser:
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];
El ORDER BY
no tiene sentido, por lo que ni siquiera debería incluirse.
Para ilustrar, usando AdventureWorks2012, aquí hay un ejemplo:
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
Y puede ver en el plan de ejecución que TOP
y ORDER BY
han sido absolutamente ignorados y optimizados por SQL Server:
No hay TOP
operador en absoluto, y ningún tipo. SQL Server los ha optimizado completamente.
Ahora, si cambia la vista para decir ORDER BY SalesID
, simplemente obtendrá el orden que indica la vista, pero solo, como se mencionó anteriormente, por coincidencia.
Pero si cambia su consulta externa para realizar el ORDER BY
querías:
SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView
ORDER BY CustomerID;
Obtienes los resultados ordenados de la forma que quieras:
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
Y el plan todavía ha optimizado el TOP
/ORDER BY
en la vista, pero se agrega una clasificación (a un costo no pequeño, eso sí) para presentar los resultados ordenados por CustomerID
:
Entonces, la moraleja de la historia, no pongas ORDER BY en vistas. Escriba ORDER BY en las consultas que los referencian. Y si la clasificación es costosa, podría considerar agregar/cambiar un índice para admitirlo.