Noget som dette burde virke i MySQL:
SELECT a.*
FROM (
SELECT ... FROM ... ORDER BY ...
) a
UNION ALL
SELECT b.*
FROM (
SELECT ... FROM ... ORDER BY ...
) b
for at returnere rækker i en rækkefølge, som vi gerne vil have dem returneret. dvs. MySQL ser ud til at respektere ORDER BY
klausuler inde i de indbyggede visninger.
Men uden en ORDER BY
klausul på den yderste forespørgsel, rækkefølgen som rækkerne returneres er ikke garanteret.
Hvis vi har brug for, at rækkerne returneres i en bestemt rækkefølge, kan vi inkludere en ORDER BY
på den yderste forespørgsel. I mange tilfælde kan vi bare bruge en ORDER BY
på den yderste forespørgsel for at tilfredsstille resultaterne.
Men når vi har et use case, hvor vi skal have alle rækkerne fra den første forespørgsel returneret før alle rækkerne fra den anden forespørgsel, er en mulighed at inkludere en ekstra diskriminatorkolonne i hver af forespørgslerne. Tilføj f.eks. ,'a' AS src
i den første forespørgsel, ,'b' AS src
til den anden forespørgsel.
Så kunne den yderste forespørgsel omfatte ORDER BY src, name
, for at garantere rækkefølgen af resultaterne.
OPFØLGNING
I din oprindelige forespørgsel er ORDER BY
i dine forespørgsler kasseres af optimeringsværktøjet; da der ikke er nogen ORDER BY
anvendt på den ydre forespørgsel, kan MySQL frit returnere rækkerne i den rækkefølge, den ønsker.
"Tricket" i mit svar (ovenfor) afhænger af adfærd, der kan være specifik for nogle versioner af MySQL.
Testtilfælde:
udfylde tabeller
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');
forespørgsel
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
resultatsæt returneret
id role
------ ---------
3 aragorn
2 frodo
5 gandalf
4 pippin
1 sam
2 boromir
3 elron
1 gimli
5 legolas
4 merry
Rækkerne fra foo2
returneres "i rækkefølge", efterfulgt af rækkerne fra foo3
, igen, "i rækkefølge".
Bemærk (igen), at denne adfærd IKKE er garanteret. (Den adfærd, vi observerer, er en bivirkning af, hvordan MySQL behandler inline-visninger (afledte tabeller). Denne adfærd kan være anderledes i versioner efter 5.5.)
Hvis du har brug for, at rækkerne returneres i en bestemt rækkefølge, skal du angive en ORDER BY
klausul for den yderste forespørgsel. Og den bestilling vil gælde for hele resultater.
Som jeg nævnte tidligere, hvis jeg havde brug for rækkerne fra den første forespørgsel først, efterfulgt af den anden forespørgsel, ville jeg inkludere en "diskriminator"-kolonne i hver forespørgsel og derefter inkludere "diskriminator"-kolonnen i ORDER BY-sætningen. Jeg ville også gøre op med de inline-visninger og gøre sådan noget:
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