Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Cara menggunakan ORDER BY di dalam UNION

Sesuatu seperti ini seharusnya bekerja di MySQL:

SELECT a.*
  FROM ( 
         SELECT ...  FROM ... ORDER BY ... 
       ) a
 UNION ALL 
SELECT b.*
  FROM ( 
         SELECT ...  FROM ... ORDER BY ... 
       ) b

untuk mengembalikan baris dalam urutan yang kami inginkan. yaitu MySQL tampaknya menghormati ORDER BY klausa di dalam tampilan sebaris.

Namun, tanpa ORDER BY klausa pada kueri terluar, urutan baris yang dikembalikan adalah bukan dijamin.

Jika kita membutuhkan baris yang dikembalikan dalam urutan tertentu, kita dapat menyertakan ORDER BY pada kueri terluar. Dalam banyak kasus penggunaan, kita cukup menggunakan ORDER BY pada kueri terluar untuk memenuhi hasil.

Tetapi ketika kami memiliki kasus penggunaan di mana kami membutuhkan semua baris dari kueri pertama dikembalikan sebelum semua baris dari kueri kedua, satu opsi adalah menyertakan kolom diskriminator tambahan di setiap kueri. Misalnya, tambahkan ,'a' AS src dalam kueri pertama, ,'b' AS src ke kueri kedua.

Kemudian kueri terluar dapat menyertakan ORDER BY src, name , untuk menjamin urutan hasil.

TINDAK LANJUT

Dalam kueri asli Anda, ORDER BY dalam kueri Anda dibuang oleh pengoptimal; karena tidak ada ORDER BY diterapkan pada kueri luar, MySQL bebas mengembalikan baris dalam urutan apa pun yang diinginkan.

"Trik" dalam kueri dalam jawaban saya (di atas) bergantung pada perilaku yang mungkin spesifik untuk beberapa versi MySQL.

Kasus uji:

mengisi tabel

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');

permintaan

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

hasil yang dikembalikan

    id  role     
 ------  ---------
      3  aragorn  
      2  frodo    
      5  gandalf  
      4  pippin   
      1  sam      
      2  boromir  
      3  elron    
      1  gimli    
      5  legolas  
      4  merry    

Baris dari foo2 dikembalikan "dalam urutan", diikuti oleh baris dari foo3 , sekali lagi, "berurutan".

Perhatikan (sekali lagi) bahwa perilaku ini TIDAK terjamin. (Perilaku yang kami amati adalah efek samping dari cara MySQL memproses tampilan sebaris (tabel turunan). Perilaku ini mungkin berbeda di versi setelah 5.5.)

Jika Anda membutuhkan baris yang dikembalikan dalam urutan tertentu, tentukan ORDER BY klausa untuk kueri terluar. Dan pemesanan itu akan berlaku untuk seluruh kumpulan hasil.

Seperti yang saya sebutkan sebelumnya, jika saya membutuhkan baris dari kueri pertama terlebih dahulu, diikuti oleh kueri kedua, saya akan menyertakan kolom "diskriminator" di setiap kueri, dan kemudian menyertakan kolom "diskriminator" di klausa ORDER BY. Saya juga akan menghapus tampilan sebaris, dan melakukan sesuatu seperti ini:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pembagian dalam kueri MySQL

  2. Bagaimana forum menunjukkan topik yang belum dibaca?

  3. salah menghitung dalam kueri

  4. Tampilkan subkategori wordpress saja

  5. AWS Aurora MySQL tanpa server:cara menghubungkan dari MySQL Workbench