SQL-Abfrage - Verwenden von Order By in UNION


83

Wie kann eine Vereinigungsabfrage programmgesteuert sortiert werden, wenn Daten aus zwei Tabellen abgerufen werden? Beispielsweise,

SELECT table1.field1 FROM table1 ORDER BY table1.field1
UNION
SELECT table2.field1 FROM table2 ORDER BY table2.field1

Wirft eine Ausnahme

Hinweis: Dies wird im MS Access Jet-Datenbankmodul versucht

Antworten:


118

Manchmal müssen Sie die ORDER BYin jedem der Abschnitte haben, mit denen kombiniert werden muss UNION.

In diesem Fall

SELECT * FROM 
(
  SELECT table1.field1 FROM table1 ORDER BY table1.field1
) DUMMY_ALIAS1

UNION ALL

SELECT * FROM
( 
  SELECT table2.field1 FROM table2 ORDER BY table2.field1
) DUMMY_ALIAS2

1
arbeitete für mich, wenn die Reihenfolge von die Ergebnismenge beeinflusst (wie bei Verwendung von Top x)
James Barrass

Genau das suche ich! Vielen Dank!
Srichand Yella

Funktioniert hervorragend für mich ... Sie müssen sicherstellen, dass die äußere Auswahl einen Tabellenalias hat. Das hat mich gebissen.
Troy

Ich hatte keine Probleme mit dieser Syntax mit Microsoft SQL Server Standard (64-Bit) Version 11.0.5058.0.
Hlovdal

3
In SSMS müssen Sie die Unterabfragen in ändern SELECT TOP 100 PERCENT, um sie ORDER BYin einer
Unterabfrage

64
SELECT field1 FROM table1
UNION
SELECT field1 FROM table2
ORDER BY field1

18
Dies erreicht technisch nicht das, was Sie in der ursprünglichen Frage logisch gestellt haben.
Ian Boyd

2
@ Ian Boyd: Ich verstehe Ihren Standpunkt, aber was sie fragen, macht keinen logischen Sinn: Union arbeitet an Sets und Sets haben keine Reihenfolge!
Tag, wenn

8
@onedaywhen Der ursprüngliche Autor möchte zwei geordnete Ergebnissätze verketten. UNIONlässt das nicht zu. Möglicherweise gibt es ein anderes Konstrukt, um dies zu tun. Möglicherweise nicht. In beiden Fällen entspricht diese Antwort technisch nicht den Anforderungen des Autors.
Ian Boyd

4
@ Ian Boyd: Ist in SQL ORDER BYTeil eines Cursors, während UNIONTabellen bearbeitet werden, weshalb deren Code nicht funktionieren kann. Ich kann nicht sehen, wie Sie die Absicht des OP aus absurdem Code ableiten können. Bedenken Sie, dass SQL UNIONDuplikate entfernt: Wenn dies Ihre "geordneten Ergebnissätze" sind, {1, 2, 3} UNION {2, 4, 6}wäre das Ergebnis {1, 2, 3, 4, 6}oder {1, 3, 2, 4, 6}? Wir wissen es nicht, weil die Vereinigung von "geordneten Ergebnissätzen" in Bezug auf SQL undefiniert ist und das OP nicht angegeben hat.
Tag, wenn

Ich verwende MYSQL und habe das Feld (Bestellfeld) in alle select-Anweisungen aufgenommen. Dann habe ich am Ende einfach Order by by hinzugefügt. Funktioniert gut für mich.
CreativeManix

57

Ich denke, das ist eine gute Erklärung.

Das Folgende ist eine UNION-Abfrage, die eine ORDER BY-Klausel verwendet:

select supplier_id, supplier_name
from suppliers
where supplier_id > 2000
UNION
select company_id, company_name
from companies
where company_id > 1000
ORDER BY 2;

Da sich die Spaltennamen zwischen den beiden "select" -Anweisungen unterscheiden, ist es vorteilhafter, die Spalten in der ORDER BY-Klausel anhand ihrer Position in der Ergebnismenge zu referenzieren.

In diesem Beispiel haben wir die Ergebnisse nach supplier_name/ company_namein aufsteigender Reihenfolge sortiert , wie durch "ORDER BY 2" angegeben.

Die Felder supplier_name/ company_namebefinden sich in der Ergebnismenge an Position 2.

Entnommen von hier: http://www.techonthenet.com/sql/union.php


28

Anhand eines konkreten Beispiels:

SELECT name FROM Folders ORDER BY name
UNION
SELECT name FROM Files ORDER BY name

Dateien:

name
=============================
RTS.exe
thiny1.etl
thing2.elt
f.txt
tcpdump_trial_license (1).zip

Ordner:

name
============================
Contacts
Desktop
Downloads
Links
Favorites
My Documents

Gewünschte Ausgabe: (Ergebnisse der ersten Auswahl zuerst, dh Ordner zuerst)

Contacts
Desktop
Downloads
Favorites
Links
My Documents
f.txt
RTMS.exe
tcpdump_trial_license (1).zip
thiny1.etl
thing2.elt

SQL, um die gewünschten Ergebnisse zu erzielen:

SELECT name 
FROM (
    SELECT 1 AS rank, name FROM Folders
    UNION 
    SELECT 2 AS rank, name FROM Files) dt
ORDER BY rank, name

3
Dies ist bei weitem die beste Antwort
javier_domenech

1
Das ist eine großartige Antwort!
Ali Gonabadi

Hinweis - Sie müssen der abgeleiteten Tabelle einen Alias ​​geben (wie in diesem Beispiel mit gezeigt dt), sonst funktioniert es nicht. Ich war eine Weile verwirrt darüber, da ich dieses Detail zunächst weggelassen hatte und die von SSMS ausgegebene Fehlermeldung nicht besonders hilfreich ist.
CactusCake

17

Hier ist ein Beispiel aus Northwind 2007:

SELECT [Product ID], [Order Date], [Company Name], [Transaction], [Quantity]
FROM [Product Orders]
UNION SELECT [Product ID], [Creation Date], [Company Name], [Transaction], [Quantity]
FROM [Product Purchases]
ORDER BY [Order Date] DESC;

Die ORDER BY-Klausel muss nur die letzte Anweisung sein, nachdem Sie alle Gewerkschaften geschlossen haben. Sie können mehrere Sätze zusammenfassen und dann nach dem letzten Satz eine ORDER BY-Klausel einfügen.


9
(SELECT table1.field1 FROM table1 
UNION
SELECT table2.field1 FROM table2) ORDER BY field1 

Arbeit? Denken Sie daran, Sets zu denken. Holen Sie sich das gewünschte Set mithilfe einer Union und führen Sie dann Ihre Operationen daran aus.


Sie können auch Ordnungswerte in Ihrer order by-Klausel verwenden, falls die Felder, nach denen Sie sortieren möchten, anders benannt sind
Anson Smith,

5
SELECT table1Column1 as col1,table1Column2 as col2
    FROM table1
UNION
(    SELECT table2Column1 as col1, table1Column2 as col2
         FROM table2
)
ORDER BY col1 ASC

4
SELECT field1
FROM ( SELECT field1 FROM table1
       UNION
       SELECT field1 FROM table2
     ) AS TBL
ORDER BY TBL.field1

(benutze ALIAS)


@DisplacedGuy Wenn MJ eine bessere Antwort auf eine Frage hat als eine der oben genannten, und in diesem Fall die akzeptierte Antwort eindeutig Probleme hat, sollte MJ in der Lage sein und ich ermutige ihn, neue Antworten zu hinterlassen
MobileMon

Und übrigens, MJs Antwort ist am besten! (zumindest für mich)
MobileMon

4

Dies ist das Dümmste, was ich je gesehen habe, aber es funktioniert, und Sie können nicht mit Ergebnissen streiten.

SELECT *
FROM (
    SELECT table1.field1 FROM table1 ORDER BY table1.field1
    UNION
    SELECT table2.field1 FROM table2 ORDER BY table2.field1
) derivedTable

Das Innere der abgeleiteten Tabelle wird nicht von alleine ausgeführt, aber als abgeleitete Tabelle funktioniert es einwandfrei. Ich habe dies auf SS 2000, SS 2005, SS 2008 R2 und allen drei Arbeiten versucht.


2

So wird es gemacht

select * from 
    (select top 100 percent pointx, pointy from point
     where pointtype = 1
     order by pointy) A
union all
select * from 
    (select top 100 percent pointx, pointy from point
     where pointtype = 2
     order by pointy desc) B

2

Beim Durchsuchen dieses Kommentarbereichs stieß ich auf zwei verschiedene Muster, die die Frage beantworteten. Leider funktioniert das zweite Muster für SQL 2012 nicht. Hier ist meine "Umgehung".


Bestellen Sie nach einer gemeinsamen Spalte

Dies ist der einfachste Fall, dem Sie begegnen können. Wie viele Benutzer bereits betont haben, müssen Sie Order Byam Ende der Abfrage nur eine hinzufügen

SELECT a FROM table1
UNION
SELECT a FROM table2
ORDER BY field1

oder

SELECT a FROM table1 ORDER BY field1
UNION
SELECT a FROM table2 ORDER BY field1

Bestellen Sie nach in verschiedenen Spalten

Hier wird es tatsächlich schwierig. Mit SQL 2012 habe ich den Top-Beitrag ausprobiert und er funktioniert nicht.

SELECT * FROM 
(
  SELECT table1.field1 FROM table1 ORDER BY table1.field1
) DUMMY_ALIAS1

UNION ALL

SELECT * FROM
( 
  SELECT table2.field1 FROM table2 ORDER BY table2.field1
) DUMMY_ALIAS2

Nach der Empfehlung im Kommentar habe ich dies versucht

SELECT * FROM 
(
  SELECT TOP 100 PERCENT table1.field1 FROM table1 ORDER BY table1.field1
) DUMMY_ALIAS1

UNION ALL

SELECT * FROM
( 
  SELECT TOP 100 PERCENT table2.field1 FROM table2 ORDER BY table2.field1
) DUMMY_ALIAS2

Dieser Code hat zwar kompiliert, aber das DUMMY_ALIAS1und DUMMY_ALIAS2überschreibt das Order Byin der SelectAnweisung festgelegte, was dies unbrauchbar macht.

Die einzige Lösung, die mir einfiel und die für mich funktionierte, bestand darin, keine Gewerkschaft zu verwenden und stattdessen die Abfragen einzeln auszuführen und sie dann zu bearbeiten. Verwenden UnionSie also im Grunde genommen kein, wenn Sie möchtenOrder By


1

Wenn Sie die Reihenfolge separat verwenden, erhält jede Teilmenge die Reihenfolge, jedoch nicht die gesamte Menge. Dies ist das, was Sie möchten, um zwei Tabellen zu vereinen.

Sie sollten so etwas verwenden, um ein bestelltes Set zu haben :

SELECT TOP (100) PERCENT field1, field2, field3, field4, field5 FROM 
(SELECT table1.field1, table1.field2, table1.field3, table1.field4, table1.field5 FROM table1
UNION ALL 
SELECT table2.field1, table2.field2, table2.field3, table2.field4, table2.field5 FROM  table2) 
AS unitedTables ORDER BY field5 DESC

0

Die zweite Tabelle kann den Tabellennamen nicht in die ORDER BYKlausel aufnehmen.

So...

SELECT table1.field1 FROM table1 ORDER BY table1.field1
UNION
SELECT table2.field1 FROM table2 ORDER BY field1

Wirft keine Ausnahme


Was für eine gute Frage das war. Können Sie feststellen, ob Ihre oder die verschachtelte Version die gewünschten Ergebnisse liefert? Oder liefern beide die gleichen Ergebnisse? Wenn ja, wäre die verschachtelte Lösung des (anderen) leistungsfähiger, da ORDER BY nur einmal ausgeführt wird?
DOK

Ich bin mir nicht sicher, ob der Leistungsvorteil des Jet-Triebwerks von Vorteil ist, aber ich würde sagen, dass die Lesbarkeit aufgrund der Verschachtelung verbessert wird.
Curtis Inderwiesche

0

Wenn nötig, um die innere Sortierung beizubehalten:

SELECT 1 as type, field1 FROM table1 
UNION 
SELECT 2 as type, field1 FROM table2 
ORDER BY type, field1

0
(SELECT FIELD1 AS NEWFIELD FROM TABLE1 ORDER BY FIELD1)
UNION
(SELECT FIELD2 FROM TABLE2 ORDER BY FIELD2)
UNION
(SELECT FIELD3 FROM TABLE3 ORDER BY FIELD3) ORDER BY NEWFIELD

Versuche dies. Es hat bei mir funktioniert.


0

Für SQL Server 2014/2012 / Andere (nicht aktiviert):

SELECT * FROM 
(
  SELECT table1.field1 FROM table1 ORDER BY table1.field1
) 
as DUMMY_ALIAS1

UNION ALL

SELECT * FROM
( 
  SELECT table2.field1 FROM table2 ORDER BY table2.field1
) 
as DUMMY_ALIAS2

2012 wird beim Kompilieren ein Kompilierungsfehler angezeigt. Das Skript funktioniert nicht für eine gespeicherte Prozedur. Sie benötigen die Top-Klausel.
Timothy Dooling
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.