Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Erstellen Sie eine Ansicht mit der ORDER BY-Klausel

Ich bin mir nicht sicher, was Sie von diesem ORDER BY halten erfüllt? Auch wenn Sie tun Geben Sie ORDER BY ein in der Ansicht auf legale Weise (z.B. durch Hinzufügen eines TOP Klausel), wenn Sie nur aus der Ansicht auswählen, z. SELECT * FROM dbo.TopUsersTest; ohne ORDER BY -Klausel steht es SQL Server frei, die Zeilen auf die effizienteste Weise zurückzugeben, was nicht unbedingt der erwarteten Reihenfolge entspricht. Das liegt daran, dass ORDER BY ist überladen, da es versucht, zwei Zwecken zu dienen:die Ergebnisse zu sortieren und festzulegen, welche Zeilen in TOP aufgenommen werden sollen . In diesem Fall TOP immer gewinnt (obwohl Sie je nach gewähltem Index zum Scannen der Daten feststellen können, dass Ihre Bestellung wie erwartet funktioniert - aber das ist nur ein Zufall).

Um das zu erreichen, was Sie wollen, müssen Sie Ihren ORDER BY hinzufügen -Klausel zu den Abfragen, die Daten aus der Ansicht ziehen, nicht zum Code der Ansicht selbst.

Ihr Ansichtscode sollte also einfach lauten:

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];

Der ORDER BY ist bedeutungslos und sollte daher nicht einmal enthalten sein.

Zur Veranschaulichung anhand von AdventureWorks2012 hier ein Beispiel:

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;

Ergebnisse:

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

Und Sie können anhand des Ausführungsplans sehen, dass die Datei TOP und ORDER BY wurden von SQL Server absolut ignoriert und wegoptimiert:

Es gibt kein TOP Betreiber überhaupt, und keine Sorte. SQL Server hat sie komplett wegoptimiert.

Wenn Sie jetzt die Ansicht ändern, um ORDER BY SalesID zu sagen , erhalten Sie dann zufällig die Reihenfolge, die die Ansicht angibt, aber nur - wie bereits erwähnt - durch Zufall.

Aber wenn Sie Ihre äußere Abfrage ändern, um ORDER BY auszuführen Sie wollten:

SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView
ORDER BY CustomerID;

Sie erhalten die Ergebnisse so geordnet, wie Sie es möchten:

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

Und der Plan hat noch den TOP wegoptimiert /ORDER BY in der Ansicht, aber es wird eine Sortierung hinzugefügt (wohlgemerkt zu nicht geringen Kosten), um die Ergebnisse sortiert nach CustomerID anzuzeigen :

Also, Moral von der Geschichte, geben Sie ORDER BY nicht in Ansichten ein. Fügen Sie ORDER BY in die Abfragen ein, die darauf verweisen. Und wenn die Sortierung kostspielig ist, sollten Sie erwägen, einen Index hinzuzufügen/zu ändern, um dies zu unterstützen.