Qualcosa del genere dovrebbe funzionare in MySQL:
SELECT a.*
FROM (
SELECT ... FROM ... ORDER BY ...
) a
UNION ALL
SELECT b.*
FROM (
SELECT ... FROM ... ORDER BY ...
) b
per restituire le righe nell'ordine in cui vorremmo che fossero restituite. cioè MySQL sembra onorare il ORDER BY
clausole all'interno delle viste inline.
Ma senza un ORDER BY
clausola sulla query più esterna, l'ordine di restituzione delle righe è non garantito.
Se abbiamo bisogno delle righe restituite in una sequenza particolare, possiamo includere un ORDER BY
sulla query più esterna. In molti casi d'uso, possiamo semplicemente usare un ORDER BY
sulla query più esterna per soddisfare i risultati.
Ma quando abbiamo un caso d'uso in cui abbiamo bisogno di tutte le righe della prima query restituite prima di tutte le righe della seconda query, un'opzione consiste nell'includere una colonna discriminante aggiuntiva in ciascuna delle query. Ad esempio, aggiungi ,'a' AS src
nella prima query, ,'b' AS src
alla seconda query.
Quindi la query più esterna potrebbe includere ORDER BY src, name
, per garantire la sequenza dei risultati.
SEGUITO
Nella tua query originale, il ORDER BY
nelle tue query viene scartato dall'ottimizzatore; poiché non esiste ORDER BY
applicato alla query esterna, MySQL è libero di restituire le righe nell'ordine che preferisce.
Il "trucco" nella query nella mia risposta (sopra) dipende dal comportamento che potrebbe essere specifico di alcune versioni di MySQL.
Caso di prova:
popolare tabelle
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');
interrogare
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
set di risultati restituito
id role
------ ---------
3 aragorn
2 frodo
5 gandalf
4 pippin
1 sam
2 boromir
3 elron
1 gimli
5 legolas
4 merry
Le righe da foo2
vengono restituiti "in ordine", seguiti dalle righe di foo3
, ancora, "in ordine".
Nota (di nuovo) che questo comportamento NON garantita. (Il comportamento che osserviamo è un effetto collaterale del modo in cui MySQL elabora le viste inline (tabelle derivate). Questo comportamento potrebbe essere diverso nelle versioni successive alla 5.5.)
Se hai bisogno delle righe restituite in un ordine particolare, specifica un ORDER BY
clausola per la query più esterna. E quell'ordine si applicherà a intero set di risultati.
Come accennato in precedenza, se avessi bisogno delle righe della prima query prima, seguite dalla seconda query, includerei una colonna "discriminatore" in ciascuna query e quindi includerei la colonna "discriminatore" nella clausola ORDER BY. Vorrei anche eliminare le viste in linea e fare qualcosa del genere:
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