Нещо подобно трябва да работи в MySQL:
SELECT a.*
FROM (
SELECT ... FROM ... ORDER BY ...
) a
UNION ALL
SELECT b.*
FROM (
SELECT ... FROM ... ORDER BY ...
) b
за връщане на редове в реда, в който бихме искали да бъдат върнати. т.е. MySQL изглежда спазва ORDER BY
клаузи във вградените изгледи.
Но без ORDER BY
клауза на най-външната заявка, редът, в който се връщат редовете, е не гарантирано.
Ако имаме нужда от редовете, върнати в определена последователност, можем да включим ORDER BY
на най-външната заявка. В много случаи на употреба можем просто да използваме ORDER BY
на най-външната заявка, за да задоволи резултатите.
Но когато имаме случай на използване, при който се нуждаем от всички редове от първата заявка, върнати преди всички редове от втората заявка, една от опциите е да включим допълнителна колона с дискриминатор във всяка от заявките. Например добавете ,'a' AS src
в първата заявка, ,'b' AS src
към втората заявка.
Тогава най-външната заявка може да включва ORDER BY src, name
, за да се гарантира последователността на резултатите.
ПОСЛЕДВАНЕ
В оригиналната ви заявка ORDER BY
във вашите заявки се отхвърля от оптимизатора; тъй като няма ORDER BY
приложен към външната заявка, MySQL е свободен да връща редовете в какъвто ред иска.
„Трикът“ в заявката в моя отговор (по-горе) зависи от поведението, което може да е специфично за някои версии на MySQL.
Тестов случай:
попълване на таблици
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');
заявка
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
върнати резултати
id role
------ ---------
3 aragorn
2 frodo
5 gandalf
4 pippin
1 sam
2 boromir
3 elron
1 gimli
5 legolas
4 merry
Редовете от foo2
се връщат "в ред", последвани от редовете от foo3
, отново "по ред".
Обърнете внимание (отново), че това поведение е НЕ гарантирано. (Поведението, което наблюдаваме, е страничен ефект от това как MySQL обработва вградени изгледи (извлечени таблици). Това поведение може да е различно във версии след 5.5.)
Ако имате нужда от връщане на редовете в определен ред, посочете ORDER BY
клауза за най-външната заявка. И това подреждане ще важи за цялото набор от резултати.
Както споменах по-рано, ако имам нужда първо от редовете от първата заявка, последвана от втората заявка, ще включа колона "дискриминатор" във всяка заявка и след това ще включа колоната "дискриминатор" в клаузата ORDER BY. Също така бих премахнал вградените изгледи и бих направил нещо подобно:
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