sql >> Databáze >  >> RDS >> Mysql

Jak používat ORDER BY uvnitř UNION

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


  1. Kde mohu získat aplikaci pro chatovací místnost PHP / MYSQL

  2. Povolit všechna vzdálená připojení, MySQL

  3. Jak vytvořit cizí klíč pomocí ON UPDATE CASCADE na Oracle?

  4. SQL Server (TSQL) - Je možné provádět příkazy paralelně?