Coś takiego powinno działać w MySQL:
SELECT a.*
FROM (
SELECT ... FROM ... ORDER BY ...
) a
UNION ALL
SELECT b.*
FROM (
SELECT ... FROM ... ORDER BY ...
) b
zwracać wiersze w kolejności, w jakiej chcielibyśmy, aby zostały zwrócone. np. MySQL wydaje się honorować ORDER BY
klauzule wewnątrz widoków wbudowanych.
Ale bez ORDER BY
klauzuli w najbardziej zewnętrznym zapytaniu, kolejność, w jakiej wiersze są zwracane, jest nie gwarantowane.
Jeśli potrzebujemy wierszy zwracanych w określonej sekwencji, możemy dołączyć ORDER BY
w zapytaniu zewnętrznym. W wielu przypadkach możemy po prostu użyć ORDER BY
na najbardziej zewnętrznym zapytaniu, aby spełnić wyniki.
Ale kiedy mamy przypadek użycia, w którym potrzebujemy wszystkich wierszy z pierwszego zapytania zwróconych przed wszystkimi wierszami z drugiego zapytania, jedną z opcji jest uwzględnienie dodatkowej kolumny dyskryminującej w każdym z zapytań. Na przykład dodaj ,'a' AS src
w pierwszym zapytaniu, ,'b' AS src
do drugiego zapytania.
Wtedy najbardziej zewnętrzne zapytanie może zawierać ORDER BY src, name
, aby zagwarantować kolejność wyników.
KONTYNUACJA
W pierwotnym zapytaniu ORDER BY
w zapytaniach jest odrzucany przez optymalizator; ponieważ nie ma ORDER BY
zastosowane do zapytania zewnętrznego, MySQL może zwracać wiersze w dowolnej kolejności.
"Sztuczka" w zapytaniu w mojej odpowiedzi (powyżej) zależy od zachowania, które może być specyficzne dla niektórych wersji MySQL.
Przypadek testowy:
wypełnij tabele
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');
zapytanie
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
zwrócono zestaw wyników
id role
------ ---------
3 aragorn
2 frodo
5 gandalf
4 pippin
1 sam
2 boromir
3 elron
1 gimli
5 legolas
4 merry
Wiersze z foo2
zwracane są "w kolejności", po których następują wiersze z foo3
, ponownie „w kolejności”.
Pamiętaj (ponownie), że to zachowanie NIE gwarantowane. (Zachowanie, które obserwujemy, jest efektem ubocznym tego, jak MySQL przetwarza widoki wbudowane (tabele pochodne). To zachowanie może być inne w wersjach po 5.5.)
Jeśli potrzebujesz wierszy zwróconych w określonej kolejności, określ ORDER BY
klauzula dla najbardziej zewnętrznego zapytania. A ta kolejność będzie dotyczyć całej zestaw wyników.
Jak wspomniałem wcześniej, gdybym najpierw potrzebował wierszy z pierwszego zapytania, a następnie z drugiego, do każdego zapytania dołączyłbym kolumnę „dyskryminator”, a następnie do klauzuli ORDER BY dołączyłem kolumnę „dyskryminator”. Zrezygnowałbym również z widoków wbudowanych i zrobiłby coś takiego:
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