SQL server: ORDER BY in Unterabfrage mit UNION

Ich habe zwei Fragen, die mit einer UNION ALL 1 kombiniert werden:

 --Query 1 SELECT Flavor, Color FROM Friends 

 --Query 2 SELECT Flavor, (SELECT TOP 1 Color FROM Rainbows WHERE Rainbows.StrangerID = Strangers.StrangerID ORDER BY Wavelength DESC ) AS Color FROM Strangers 

Beide, die natürlich selbstverständlich gut funktionieren, aber in Verbindung mit einer UNION ALL :

 SELECT Flavor, Color FROM Friends UNION ALL SELECT Flavor, (SELECT TOP 1 Color FROM Rainbows WHERE Rainbows.StrangerID = Strangers.StrangerID ORDER BY Wavelength DESC ) AS Color FROM Strangers 

Die Abfrage schlägt mit dem Fehler fehl:

Msg 104, Stufe 15, Zustand 1, Zeile 3
ORDER BY-Elemente müssen in der Auswahlliste erscheinen, wenn die statement einen UNION-Operator enthält.

Wie verwende ich einen ORDER BY in einer Erklärung mit einem UNION ALL?

Copy-Pasteable Beispiel

 CREATE TABLE Friends (Flavor int, Color int) CREATE TABLE Strangers (Flavor int, StrangerID int) CREATE TABLE Rainbows (StrangerID int, Color int, Wavelength int) go SELECT Flavor, Color FROM Friends UNION ALL SELECT Flavor, (SELECT TOP 1 Color FROM Rainbows WHERE Rainbows.StrangerID = Strangers.StrangerID ORDER BY Wavelength DESC ) AS Color FROM Strangers go DROP TABLE Rainbows DROP TABLE Strangers DROP TABLE Friends 

server: Msg 104, Ebene 15, Zustand 1, Zeile 2
ORDER BY-Elemente müssen in der Auswahlliste erscheinen, wenn die statement einen UNION-Operator enthält.

Fußnoten

  • 1 Konstruktives hypothetisches Beispiel Oder nicht.

Siehe auch

  • SQL Query – Verwenden von Order By in UNION
  • SQL UNION und ORDER BY
  • SQL: Verwenden von Top 1 in UNION-Abfrage mit Order By
  • Einfluss der Reihenfolge der korrelierten Unterabfragen innerhalb einer Projektion

Ein bisschen ein Hack, aber das wird funktionieren.

 CREATE TABLE Friends (Flavor int, Color int) CREATE TABLE Strangers (Flavor int, StrangerID int) CREATE TABLE Rainbows (StrangerID int, Color int, Wavelength int) go SELECT Flavor, Color FROM Friends UNION ALL SELECT Flavor, (SELECT Color FROM (SELECT TOP 1 Color, Wavelength FROM Rainbows WHERE Rainbows.StrangerID = Strangers.StrangerID ORDER BY Wavelength DESC ) AS Foo ) AS Color FROM Strangers go DROP TABLE Rainbows DROP TABLE Strangers DROP TABLE Friends 

Eigentlich betrachte ich die Problemumgehung von diesem Link, den ich kommentiert habe, vielleicht möchtest du das versuchen:

 SELECT Flavor, Color FROM Friends UNION ALL SELECT Flavor, (SELECT TOP 1 Color FROM (SELECT Color, Wavelength FROM Rainbows WHERE Rainbows.StrangerID = Strangers.StrangerID ) X ORDER BY Wavelength DESC) AS Color FROM Strangers 

… oder irgendeine ähnliche Art von Ding zu versuchen, den Motor in nicht beschweren zu täuschen.

Aber ich kann es nicht testing, ich fürchte mich; Ich glaube nicht, dass wir eine 2000 Box im Gebäude haben, virtuell oder anders.

EDIT: Ah! Sieht aus wie Joe und ich überlappte auf unsere Sneakiness 🙂

Ich weiß, dass du einen CTE (Common Table Expression) benutzen kannst, wo du deine Bestellung für den CTE verwenden kannst.

 ;with results as ( SELECT Cassettes.CassetteNumber, LastCassetteTransfers.Amount, CassetteTransfers.CreatedDate FROM Cassettes INNER JOIN LastCassetteTransfers ON Cassettes.CassetteGUID = LastCassetteTransfers.CassetteGUID UNION ALL SELECT Cassettes.CassetteNumber, ( SELECT TOP 1 CassetteTransfers.Amount FROM CassetteTransfers WHERE CassetteTransfers.CassetteGUID = Cassettes.CassetteGUID AND CassetteTransfers.Mode = 'ctmLoad' ) AS Amount, CassetteTransfers.CreatedDate FROM Cassettes ) SELECT CassetNumber, Amount FROM results ORDER BY CassetteTransfers.CreatedDate DESC, CassetteTransfers.Amount ( ;with results as ( SELECT Cassettes.CassetteNumber, LastCassetteTransfers.Amount, CassetteTransfers.CreatedDate FROM Cassettes INNER JOIN LastCassetteTransfers ON Cassettes.CassetteGUID = LastCassetteTransfers.CassetteGUID UNION ALL SELECT Cassettes.CassetteNumber, ( SELECT TOP 1 CassetteTransfers.Amount FROM CassetteTransfers WHERE CassetteTransfers.CassetteGUID = Cassettes.CassetteGUID AND CassetteTransfers.Mode = 'ctmLoad' ) AS Amount, CassetteTransfers.CreatedDate FROM Cassettes ) SELECT CassetNumber, Amount FROM results ORDER BY CassetteTransfers.CreatedDate DESC, CassetteTransfers.Amount ( ;with results as ( SELECT Cassettes.CassetteNumber, LastCassetteTransfers.Amount, CassetteTransfers.CreatedDate FROM Cassettes INNER JOIN LastCassetteTransfers ON Cassettes.CassetteGUID = LastCassetteTransfers.CassetteGUID UNION ALL SELECT Cassettes.CassetteNumber, ( SELECT TOP 1 CassetteTransfers.Amount FROM CassetteTransfers WHERE CassetteTransfers.CassetteGUID = Cassettes.CassetteGUID AND CassetteTransfers.Mode = 'ctmLoad' ) AS Amount, CassetteTransfers.CreatedDate FROM Cassettes ) SELECT CassetNumber, Amount FROM results ORDER BY CassetteTransfers.CreatedDate DESC, CassetteTransfers.Amount ) ;with results as ( SELECT Cassettes.CassetteNumber, LastCassetteTransfers.Amount, CassetteTransfers.CreatedDate FROM Cassettes INNER JOIN LastCassetteTransfers ON Cassettes.CassetteGUID = LastCassetteTransfers.CassetteGUID UNION ALL SELECT Cassettes.CassetteNumber, ( SELECT TOP 1 CassetteTransfers.Amount FROM CassetteTransfers WHERE CassetteTransfers.CassetteGUID = Cassettes.CassetteGUID AND CassetteTransfers.Mode = 'ctmLoad' ) AS Amount, CassetteTransfers.CreatedDate FROM Cassettes ) SELECT CassetNumber, Amount FROM results ORDER BY CassetteTransfers.CreatedDate DESC, CassetteTransfers.Amount 

Das soll helfen Das Wichtige thig ist, um sicherzustellen, dass Sie Ihre Bestellung durch Spalten in der inneren Abfrage (in diesem Fall der CTE) zurückgegeben haben.

Lass mich wissen, wie es funktioniert