So etwas sollte in MySQL funktionieren:
SELECT a.*
FROM (
SELECT ... FROM ... ORDER BY ...
) a
UNION ALL
SELECT b.*
FROM (
SELECT ... FROM ... ORDER BY ...
) b
um Zeilen in einer Reihenfolge zurückzugeben, die wir gerne zurückgeben möchten. d.h. MySQL scheint den ORDER BY
zu berücksichtigen Klauseln innerhalb der Inline-Ansichten.
Aber ohne ORDER BY
-Klausel in der äußersten Abfrage ist die Reihenfolge, in der die Zeilen zurückgegeben werden, nicht garantiert.
Wenn wir die zurückgegebenen Zeilen in einer bestimmten Reihenfolge benötigen, können wir einen ORDER BY
einfügen auf der äußersten Abfrage. In vielen Anwendungsfällen können wir einfach einen ORDER BY
verwenden auf der äußersten Abfrage, um die Ergebnisse zu erfüllen.
Aber wenn wir einen Anwendungsfall haben, in dem wir alle Zeilen aus der ersten Abfrage vor allen Zeilen aus der zweiten Abfrage zurückgeben müssen, besteht eine Möglichkeit darin, eine zusätzliche Diskriminatorspalte in jede der Abfragen aufzunehmen. Fügen Sie beispielsweise ,'a' AS src
hinzu in der ersten Abfrage ,'b' AS src
zur zweiten Abfrage.
Dann könnte die äußerste Abfrage ORDER BY src, name
enthalten , um die Reihenfolge der Ergebnisse zu gewährleisten.
NACHVERFOLGUNG
In Ihrer ursprünglichen Abfrage der ORDER BY
in Ihren Abfragen wird vom Optimierer verworfen; da es kein ORDER BY
gibt Auf die äußere Abfrage angewendet, kann MySQL die Zeilen in beliebiger Reihenfolge zurückgeben.
Der "Trick" bei der Abfrage in meiner Antwort (oben) hängt vom Verhalten ab, das für einige Versionen von MySQL spezifisch sein kann.
Testfall:
Tabellen füllen
CREATE TABLE foo2 (id INT PRIMARY KEY, role VARCHAR(20)) ENGINE=InnoDB;
CREATE TABLE foo3 (id INT PRIMARY KEY, role VARCHAR(20)) ENGINE=InnoDB;
INSERT INTO foo2 (id, role) VALUES
(1,'sam'),(2,'frodo'),(3,'aragorn'),(4,'pippin'),(5,'gandalf');
INSERT INTO foo3 (id, role) VALUES
(1,'gimli'),(2,'boromir'),(3,'elron'),(4,'merry'),(5,'legolas');
Abfrage
SELECT a.*
FROM ( SELECT s.id, s.role
FROM foo2 s
ORDER BY s.role
) a
UNION ALL
SELECT b.*
FROM ( SELECT t.id, t.role
FROM foo3 t
ORDER BY t.role
) b
Ergebnismenge zurückgegeben
id role
------ ---------
3 aragorn
2 frodo
5 gandalf
4 pippin
1 sam
2 boromir
3 elron
1 gimli
5 legolas
4 merry
Die Zeilen von foo2
werden "in der Reihenfolge" zurückgegeben, gefolgt von den Zeilen von foo3
, wieder "in Ordnung".
Beachten Sie (erneut), dass dieses Verhalten NICHT ist garantiert. (Das Verhalten, das wir beobachten, ist ein Nebeneffekt davon, wie MySQL Inline-Ansichten (abgeleitete Tabellen) verarbeitet. Dieses Verhalten kann in Versionen nach 5.5 anders sein.)
Wenn Sie die Zeilen in einer bestimmten Reihenfolge zurückgeben möchten, geben Sie ORDER BY
an -Klausel für die äußerste Abfrage. Und diese Reihenfolge gilt für das gesamte Ergebnismenge.
Wie ich bereits erwähnt habe, würde ich, wenn ich zuerst die Zeilen aus der ersten Abfrage benötigte, gefolgt von der zweiten Abfrage, eine "Diskriminator"-Spalte in jede Abfrage aufnehmen und dann die "Diskriminator"-Spalte in die ORDER BY-Klausel aufnehmen. Ich würde auch die Inline-Ansichten abschaffen und so etwas tun:
SELECT s.id, s.role, 's' AS src
FROM foo2 s
UNION ALL
SELECT t.id, t.role, 't' AS src
FROM foo3 t
ORDER BY src, role