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

MYSQL menunjukkan baris yang salah saat menggunakan GROUP BY

Ini adalah rintangan klasik yang dihadapi sebagian besar programmer MySQL.

  • Anda memiliki kolom ticket_id itulah argumen untuk GROUP BY . Nilai yang berbeda dalam kolom ini menentukan grup.
  • Anda memiliki kolom incoming_time itu adalah argumen untuk MAX() . Nilai terbesar di kolom ini di atas baris di setiap grup dikembalikan sebagai nilai MAX() .
  • Anda memiliki semua kolom artikel tabel lainnya. Nilai yang dikembalikan untuk kolom ini bersifat arbitrer, bukan dari baris yang sama tempat MAX() nilai terjadi.

Basis data tidak dapat menyimpulkan bahwa Anda menginginkan nilai dari baris yang sama tempat nilai maksimum muncul.

Pikirkan tentang kasus berikut:

  • Ada beberapa baris di mana nilai maks yang sama muncul. Baris mana yang harus digunakan untuk menampilkan kolom article.* ?

  • Anda menulis kueri yang mengembalikan MIN() dan MAX() . Ini legal, tetapi baris mana yang harus article.* tampilkan?

    SELECT article.* , MIN(article.incoming_time), MAX(article.incoming_time)
    FROM ticket, article
    WHERE ticket.id = article.ticket_id
    AND ticket.queue_id = 1
    GROUP BY article.ticket_id
    
  • Anda menggunakan fungsi agregat seperti AVG() atau SUM() , di mana tidak ada baris yang memiliki nilai tersebut. Bagaimana database menebak baris mana yang akan ditampilkan?

    SELECT article.* , AVG(article.incoming_time)
    FROM ticket, article
    WHERE ticket.id = article.ticket_id
    AND ticket.queue_id = 1
    GROUP BY article.ticket_id
    

Di sebagian besar merek basis data -- serta standar SQL itu sendiri -- Anda tidak diizinkan untuk menulis kueri seperti ini, karena ambiguitas. Anda tidak dapat menyertakan kolom apa pun dalam daftar pilih yang tidak ada di dalam fungsi agregat atau diberi nama di GROUP BY klausa.

MySQL lebih permisif. Ini memungkinkan Anda melakukan ini, dan membiarkan Anda menulis kueri tanpa ambiguitas. Jika Anda memiliki ambiguitas, ini akan memilih nilai dari baris yang secara fisik berada di urutan pertama dalam grup (tetapi ini tergantung pada mesin penyimpanan).

Untuk apa nilainya, SQLite juga memiliki perilaku ini, tetapi memilih terakhir baris dalam kelompok untuk menyelesaikan ambiguitas. pergilah. Jika standar SQL tidak mengatakan apa yang harus dilakukan, itu terserah implementasi vendor.

Berikut pertanyaan yang dapat memecahkan masalah Anda:

SELECT a1.* , a1.incoming_time AS maxtime
FROM ticket t JOIN article a1 ON (t.id = a1.ticket_id)
LEFT OUTER JOIN article a2 ON (t.id = a2.ticket_id 
  AND a1.incoming_time < a2.incoming_time)
WHERE t.queue_id = 1
  AND a2.ticket_id IS NULL;

Dengan kata lain, cari baris (a1 ) yang tidak memiliki baris lain (a2 ) dengan ticket_id yang sama dan incoming_time . yang lebih besar . Jika tidak ada incoming_time . yang lebih besar ditemukan, LEFT OUTER JOIN mengembalikan NULL alih-alih kecocokan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL mengabaikan batasan NOT NULL

  2. Grup Mysql DateTime dengan 15 menit

  3. PHP - Pemberitahuan:Indeks tidak terdefinisi:

  4. Memblokir '0000-00-00' dari Kolom Tanggal MySQL

  5. mysql order by, null dulu, dan DESC setelahnya