Něco takového by mělo fungovat v MySQL:
SELECT a.*
FROM (
SELECT ... FROM ... ORDER BY ...
) a
UNION ALL
SELECT b.*
FROM (
SELECT ... FROM ... ORDER BY ...
) b
vrátit řádky v pořadí, v jakém je chceme vrátit. tj. zdá se, že MySQL dodržuje ORDER BY
klauzule uvnitř inline pohledů.
Ale bez ORDER BY
klauzule na nejvzdálenějším dotazu, pořadí, ve kterém jsou vráceny řádky, není zaručeno.
Pokud potřebujeme řádky vrácené v určité sekvenci, můžeme zahrnout ORDER BY
na nejvzdálenější dotaz. V mnoha případech použití stačí použít ORDER BY
na nejvzdálenější dotaz, aby byly splněny výsledky.
Ale když máme případ použití, kdy potřebujeme, aby se všechny řádky z prvního dotazu vrátily před všechny řádky z druhého dotazu, jednou z možností je zahrnout do každého z dotazů další sloupec diskriminátoru. Přidejte například ,'a' AS src
v prvním dotazu ,'b' AS src
na druhý dotaz.
Potom by nejvzdálenější dotaz mohl obsahovat ORDER BY src, name
, aby bylo zaručeno pořadí výsledků.
NÁSLEDOVAT
V původním dotazu ORDER BY
ve vašich dotazech je optimalizátorem zahozena; protože neexistuje žádný ORDER BY
při použití na vnější dotaz může MySQL vracet řádky v libovolném pořadí.
"Trik" v dotazu v mé odpovědi (výše) závisí na chování, které může být specifické pro některé verze MySQL.
Testovací případ:
naplnit tabulky
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');
dotaz
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
sada výsledků vrácena
id role
------ ---------
3 aragorn
2 frodo
5 gandalf
4 pippin
1 sam
2 boromir
3 elron
1 gimli
5 legolas
4 merry
Řádky z foo2
jsou vráceny "v pořadí", za nimiž následují řádky z foo3
, opět "v pořádku".
Všimněte si (opět), že toto chování NENÍ zaručena. (Chování, které pozorujeme, je vedlejším efektem toho, jak MySQL zpracovává inline pohledy (odvozené tabulky). Toto chování se může ve verzích po 5.5 lišit.)
Pokud potřebujete, aby se řádky vrátily v určitém pořadí, zadejte ORDER BY
klauzule pro nejvzdálenější dotaz. A toto řazení se bude týkat celého sada výsledků.
Jak jsem již zmínil dříve, pokud bych potřeboval nejprve řádky z prvního dotazu a poté z druhého dotazu, zahrnul bych do každého dotazu sloupec „diskriminátor“ a poté do klauzule ORDER BY zahrnul sloupec „diskriminátor“. Také bych skoncoval s inline pohledy a udělal něco takového:
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