Algo assim deve funcionar no MySQL:
SELECT a.*
FROM (
SELECT ... FROM ... ORDER BY ...
) a
UNION ALL
SELECT b.*
FROM (
SELECT ... FROM ... ORDER BY ...
) b
para retornar linhas em uma ordem que gostaríamos que fossem retornadas. ou seja, o MySQL parece honrar o
ORDER BY
cláusulas dentro das visualizações embutidas. Mas, sem um
ORDER BY
cláusula na consulta mais externa, a ordem em que as linhas são retornadas é não garantido. Se precisarmos das linhas retornadas em uma sequência específica, podemos incluir um
ORDER BY
na consulta mais externa. Em muitos casos de uso, podemos usar apenas um ORDER BY
na consulta mais externa para satisfazer os resultados. Mas quando temos um caso de uso em que precisamos de todas as linhas da primeira consulta retornadas antes de todas as linhas da segunda consulta, uma opção é incluir uma coluna discriminadora extra em cada uma das consultas. Por exemplo, adicione
,'a' AS src
na primeira consulta, ,'b' AS src
para a segunda consulta. Em seguida, a consulta mais externa pode incluir
ORDER BY src, name
, para garantir a sequência dos resultados. ACOMPANHAMENTO
Em sua consulta original, o
ORDER BY
em suas consultas é descartado pelo otimizador; já que não há ORDER BY
aplicado à consulta externa, o MySQL é livre para retornar as linhas na ordem que desejar. O "truque" na consulta na minha resposta (acima) depende do comportamento que pode ser específico de algumas versões do MySQL.
Caso de teste:
preencher tabelas
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');
inquerir
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
conjunto de resultados retornado
id role
------ ---------
3 aragorn
2 frodo
5 gandalf
4 pippin
1 sam
2 boromir
3 elron
1 gimli
5 legolas
4 merry
As linhas de
foo2
são retornados "em ordem", seguidos pelas linhas de foo3
, novamente, "em ordem". Observe (novamente) que esse comportamento NÃO garantido. (O comportamento que observamos é um efeito colateral de como o MySQL processa visualizações inline (tabelas derivadas). Esse comportamento pode ser diferente em versões posteriores à 5.5.)
Se você precisar das linhas retornadas em uma ordem específica, especifique um
ORDER BY
cláusula para a consulta mais externa. E essa ordenação se aplicará a toda conjunto de resultados. Como mencionei anteriormente, se eu precisasse primeiro das linhas da primeira consulta, seguida da segunda consulta, incluiria uma coluna "discriminador" em cada consulta e, em seguida, incluiria a coluna "discriminador" na cláusula ORDER BY. Eu também acabaria com as visualizações inline e faria algo assim:
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