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

Apakah MySQL melanggar standar dengan mengizinkan memilih kolom yang bukan bagian dari grup berdasarkan klausa?

SQL standar akan menolak kueri Anda karena Anda tidak dapat PILIH bidang non-agregat yang bukan bagian dari klausa GROUP BY dalam kueri agregat

Ini benar, hingga 1992 .

Tapi itu jelas salah, dari tahun 2003 dan seterusnya.

Dari standar SQL-2003, 6IWD6-02-Foundation-2011-01.pdf, dari http ://www.wiscorp.com/ , paragraf-7.12 (spesifikasi kueri), halaman 398 :

  1. Jika T adalah tabel berkelompok, maka misalkan G adalah himpunan kolom pengelompokan T. Dalam setiap ((ekspresi nilai)) yang terkandung di ((pilih daftar)) , setiap referensi kolom yang mereferensikan kolom T harus mereferensikan beberapa kolom C yang bergantung secara fungsional di G atau harus terisi dalam argumen gabungan dari ((set spesifikasi fungsi))yang kueri agregasinya adalah QS

Sekarang MYSQL, telah mengimplementasikan fitur ini dengan mengizinkan tidak hanya kolom yang bergantung secara fungsional pada kolom pengelompokan tetapi mengizinkan semua kolom . Hal ini menyebabkan beberapa masalah dengan pengguna yang tidak memahami cara kerja pengelompokan dan mendapatkan hasil yang tidak pasti di tempat yang tidak mereka harapkan.

Tetapi Anda benar untuk mengatakan bahwa MySQL telah menambahkan fitur yang bertentangan dengan standar SQL (walaupun Anda tampaknya berpikir demikian karena alasan yang salah). Ini tidak sepenuhnya akurat karena mereka telah menambahkan fitur standar SQL tetapi tidak dalam cara terbaik (lebih seperti cara mudah) tetapi bertentangan dengan standar terbaru.

Untuk menjawab pertanyaan Anda, alasan fitur (ekstensi) MySQL ini menurut saya sesuai dengan standar SQL terbaru (2003+). Mengapa mereka memilih untuk menerapkannya dengan cara ini (tidak sepenuhnya sesuai), kami hanya bisa berspekulasi.

Seperti yang dijawab @Quassnoi dan @Johan dengan contoh, ini terutama masalah kinerja dan pemeliharaan. Tetapi seseorang tidak dapat dengan mudah mengubah RDBMS menjadi cukup pintar (tidak termasuk Skynet) untuk mengenali kolom yang bergantung secara fungsional, jadi pengembang MySQL membuat pilihan:

Kami (MySQL) memberi Anda (pengguna MySQL) fitur ini yang ada dalam standar SQL-2003. Ini meningkatkan kecepatan dalam GROUP BY tertentu pertanyaan tapi ada tangkapan. Anda harus berhati-hati (dan bukan mesin SQL) sehingga kolom di SELECT dan HAVING daftar secara fungsional bergantung pada GROUP BY kolom. Jika tidak, Anda mungkin mendapatkan hasil yang tidak pasti.

Jika Anda ingin menonaktifkannya, Anda dapat mengatur sql_mode ke ONLY_FULL_GROUP_BY .

Semuanya ada di dokumen MySQL:Ekstensi ke GROUP BY (5.5) - meskipun tidak dalam kata-kata di atas tetapi seperti dalam kutipan Anda (mereka bahkan lupa menyebutkan bahwa itu adalah penyimpangan dari standar SQL-2003 sementara bukan standar SQL-92). Pilihan semacam ini umum saya pikir di semua perangkat lunak, termasuk RDBMS lainnya. Mereka dibuat untuk kinerja, kompatibilitas mundur dan banyak alasan lainnya. Oracle memiliki '' is the same as NULL misalnya dan SQL-Server mungkin memiliki beberapa juga.

Ada juga posting blog ini oleh Peter Bouman, di mana pilihan pengembang MySQL dipertahankan:Membongkar KELOMPOK MENURUT mitos .

Pada tahun 2011, sebagai @Mark Byers memberi tahu kami dalam komentar (dalam pertanyaan terkait di DBA.SE), PostgreSQL 9.1 menambahkan fitur baru (tanggal rilis:September 2011) dirancang untuk tujuan ini. Ini lebih membatasi daripada implementasi MySQL dan lebih mendekati standar.

Kemudian, pada tahun 2015 MySQL mengumumkan bahwa dalam versi 5.7, perilaku ditingkatkan agar sesuai dengan standar dan benar-benar mengenali dependensi fungsional, (bahkan lebih baik daripada implementasi Postgres). Dokumentasi:Penanganan MySQL dari GROUP BY (5.7) dan posting blog lain oleh Peter Bouman:MySQL 5.7.5:GROUP BY menghormati dependensi fungsional!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Fungsi MySQL GREATEST() – Temukan Argumen Terbesar dalam Daftar Argumen

  2. Cara memulai, memulai ulang, memeriksa status, dan menghentikan server MySQL

  3. MySQL – Perbaiki Kesalahan – Entri Duplikat Kesalahan Database WordPress untuk kunci PRIMARY for Query INSERT INTO wp_options

  4. Cara Meningkatkan MySQL 5.5 ke 5.6 di Ubuntu 14.04

  5. MySQL gagal pada:mysql ERROR 1524 (HY000):Plugin 'auth_socket' tidak dimuat