Daftar SELECT tidak ada dalam klausa GROUP BY dan berisi kolom tidak teragregasi… tidak sesuai dengan sql_mode = only_full_group_by

134

AM menggunakan MySQL 5.7.13 di PC windows saya dengan WAMP Server

Di sini Masalah saya adalah Saat menjalankan kueri ini

SELECT *
FROM `tbl_customer_pod_uploads`
WHERE `load_id` = '78' AND
      `status` = 'Active'
GROUP BY `proof_type`

Saya selalu mendapatkan kesalahan seperti ini

Ekspresi # 1 dari daftar SELECT tidak ada dalam klausa GROUP BY dan berisi kolom nonagregasi 'returntr_prod.tbl_customer_pod_uploads.id' yang tidak bergantung secara fungsional pada kolom dalam klausa GROUP BY; ini tidak sesuai dengan sql_mode = only_full_group_by

Bisakah Anda memberi tahu saya solusi terbaik ...

Saya membutuhkan Hasil seperti

+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
| id | user_id | load_id | bill_id | latitude | langitude | proof_type | document_type | file_name    | is_private | status | createdon           | updatedon           |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
|  1 |       1 | 78      | 1       | 21.1212  | 21.5454   |          1 |             1 | id_Card.docx |          0 | Active | 2017-01-27 11:30:11 | 2017-01-27 11:30:14 |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
Dhanu K
sumber
12
Jangan gunakan SELECT *.
shmosel
mengatakan seperti ini SELECT id FROM tbl_customer_pod_uploadsWHERE load_id= '78' AND status= 'Active' GROUP BYproof_type
Dhanu K
2
Jika Anda menginginkan kompatibilitas untuk kueri lama, Anda dapat menonaktifkan only_full_group_bymode SQL.
Barmar
5
Coba gunakan ANY_VALUE (proof_type): dev.mysql.com/doc/refman/5.7/en/group-by-handling.html SELECT *, ANY_VALUE (proof_type) FROM tbl_customer_pod_uploadsWHERE load_id= '78' AND status= 'Active' GROUP BYproof_type
AlexGach

Jawaban:

258

Ini

Ekspresi # 1 dari daftar SELECT tidak ada dalam klausa GROUP BY dan berisi kolom nonagregasi 'returntr_prod.tbl_customer_pod_uploads.id' yang tidak bergantung secara fungsional pada kolom dalam klausa GROUP BY; ini tidak sesuai dengan sql_mode = only_full_group_by

akan diselesaikan dengan mengubah mode sql di MySQL dengan perintah ini,

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

Ini juga berfungsi untuk saya .. Saya menggunakan ini, karena dalam proyek saya ada banyak Queries seperti ini jadi saya hanya mengubah mode sql ini menjadi only_full_group_by

Terima kasih... :-)

Dhanu K
sumber
14
Ini bekerja untuk saya !. Anda menyelamatkan hari saya. Ingatlah untuk
MEMULIHKAN
2
Jika saya menggunakan codeigniter dan saya ingin mengeksekusi dalam model, lalu bagaimana saya menggunakannya? Bisa bantu saya ? @marcodeely
DhavalThakor
@DhavalThakor, setelah Anda menjalankan kueri ini di server Anda, Anda tidak perlu menjalankannya lagi dan lagi. jadi Anda tidak perlu memasukkannya ke dalam model Anda
Dhanu K
2
MySQL 5.7.29, tidak perlu memulai ulang layanan
Taavi
Saya menggunakan versi server: 5.7.31-0ubuntu0.16.04.1 - (Ubuntu), dan setiap kali saya memulai mesin saya, saya mengaturnya setiap saat, Apakah ada perbaikan permanen untuk ini?
Arpita Hunka
80

Ketika only_full_group_bymode MySQL diaktifkan, itu berarti aturan ANSI SQL yang ketat akan berlaku saat menggunakan GROUP BY. Berkenaan dengan kueri Anda, ini berarti bahwa jika Anda GROUP BYdari proof_typekolom, maka Anda hanya dapat memilih dua hal:

  • yang proof_typekolom, atau
  • agregat dari kolom lain


Dengan "agregat" dari kolom lain, maksud saya menggunakan fungsi agregat seperti MIN(), MAX()atau AVG()dengan kolom lain. Jadi dalam kasus Anda, kueri berikut akan valid:

SELECT proof_type,
       MAX(id) AS max_id,
       MAX(some_col),
       MIN(some_other_col)
FROM tbl_customer_pod_uploads
WHERE load_id = '78' AND
      status = 'Active'
GROUP BY proof_type

Sebagian besar GROUP BYpertanyaan MySQL yang saya lihat di SO memiliki mode ketat dimatikan, sehingga kueri berjalan, tetapi dengan hasil yang salah. Dalam kasus Anda, kueri tidak akan berjalan sama sekali, memaksa Anda untuk memikirkan tentang apa yang sebenarnya ingin Anda lakukan.

Catatan: ANSI SQL memperluas apa yang diizinkan untuk dipilih GROUP BYdengan juga menyertakan kolom yang secara fungsional bergantung pada kolom yang dipilih. Contoh ketergantungan fungsional akan dikelompokkan berdasarkan kolom kunci utama dalam sebuah tabel. Karena kunci utama dijamin unik untuk setiap rekaman, oleh karena itu nilai kolom lain juga akan ditentukan. MySQL adalah salah satu database yang memungkinkan untuk ini (SQL Server dan Oracle tidak AFAIK).

Tim Biegeleisen
sumber
2
Hanya satu catatan: Hasilnya tidak salah (mengikuti aturan MySQL), tetapi tidak dapat diprediksi, artinya, kolom yang bukan bagian dari grup oleh dan tidak dikumpulkan (dan tidak bergantung secara fungsional) akan mengembalikan nilai 'acak' dari grup yang sesuai. Seperti yang dinyatakan dalam manual: "server bebas memilih nilai apa pun dari setiap grup"
Sebelum
Melanggar pengelompokan ketat tidak selalu menghasilkan hasil yang salah. Saya biasanya melakukannya ketika bidang dijamin identik (misalnya gabungan satu-ke-banyak). Dan meskipun tidak dijamin, memilih baris arbitrer sering kali tidak lagi salah dibandingkan menggunakan fungsi agregat atau menambahkan tingkat pengelompokan.
shmosel
1
1 untuk saya. Saya tidak tahu mengapa jawaban yang "diterima" di atas diterima. Cara Anda adalah cara yang benar dan jawaban yang diterima adalah perbaikan hacky biasa yang akan menyebabkan lebih banyak masalah di masa depan.
Jcov
1
@Jcov ... dan saya tidak setuju dengan komentar Anda lagi +1. Mematikan pembatasan ANSI GROUP BYhampir selalu merupakan ide yang buruk. Saya takut bahwa begitu banyak pengguna yang mengambil saran yang salah dan menggunakannya.
Tim Biegeleisen
1
@TimBiegeleisen selamat datang di pengembangan salin + tempel modern. "Saya tidak perlu berpikir, seseorang yang telah membaca sesuatu secara acak di suatu tempat dari sumber yang tidak dapat dipercaya telah melakukan pemikiran untuk saya".
Jcov
48

Gunakan salah satu solusi

(1) PHPMyAdmin

jika Anda menggunakan phpMyAdmin, ubah pengaturan " sql_mode " seperti yang disebutkan pada gambar di bawah. masukkan deskripsi gambar di sini

Edit variabel "mode sql" dan hapus teks "ONLY_FULL_GROUP_BY" dari nilainya

(2) SQL / Command prompt Jalankan perintah di bawah ini.

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

(3) Jangan gunakan SELECT *

Gunakan kolom yang relevan dalam kueri PILIH. relevan berarti kolom, yang ada di klausa "kelompok menurut" atau kolom dengan fungsi agregat (MAX, MIN, SUM, COUNT dll)


Catatan penting

Perubahan yang dibuat dengan menggunakan poin (1) ATAU poin (2) tidak akan mengaturnya secara PERMANEN, dan akan kembali setelah setiap restart.

Jadi Anda harus mengatur ini di file konfigurasi Anda (misalnya /etc/mysql/my.cnf di bagian [mysqld]), sehingga perubahan tetap berlaku setelah MySQL dimulai ulang:

File Konfigurasi: /etc/mysql/my.cnf

Nama variabel : sql_mode OR sql-mode

Rakesh Soni
sumber
Terima kasih banyak atas jawaban di atas. Saya ingin mengubah ini seperti yang Anda katakan di my.cnf saya. Tetapi ketika saya membuka file itu, itu hanya terbuka dalam mode hanya-baca. Ada bantuan atau link referensi ???. Saya menggunakan Ubuntu 16.04
Sanmitha Sadhishkumar
1
(1) Ubah izin file my.cnf dengan menggunakan perintah "chmod". (2) Lakukan perubahan di my.cnf (3) setel hanya baca lagi (ubah izin file lagi menggunakan "chmod") (4) restart mysql
Rakesh Soni
21

Metode di bawah ini memecahkan masalah saya:

Di ubuntu

Tipe: sudo vi /etc/mysql/my.cnf

ketik A untuk masuk ke mode penyisipan

Di baris terakhir tempelkan di bawah dua kode baris:

[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Ketik esc untuk keluar dari mode masukan

Type :wq to save and close vim.

Ketik sudo service mysql restartuntuk memulai ulang MySQL.

Anand Huded
sumber
1
terima kasih, berhasil! di cent os, whm, my.cnf terletak di sudo vi /etc/my.cnf
/etc/my.cnf
19

Anda dapat menonaktifkan sql_mode = only_full_group_by dengan beberapa perintah, Anda dapat mencoba ini dengan terminal atau MySql IDE

mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Anil Gupta
sumber
11

Di Ubuntu

Langkah 1:

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

Langkah 2: Pergi ke baris terakhir dan tambahkan yang berikut ini

sql_mode = ""

Langkah 3: Simpan

Langkah 4: Mulai ulang server mysql.

Gullu Mutullu
sumber
9

Agar kueri menjadi legal di SQL92, kolom nama harus dihilangkan dari daftar pilih atau dinamai di klausa GROUP BY.

SQL99 dan yang lebih baru mengizinkan nonagregat tersebut per fitur opsional T301 jika mereka secara fungsional bergantung pada kolom GROUP BY: Jika ada hubungan seperti itu antara nama dan custid, kueri legal. Ini akan menjadi kasus, misalnya, jika custid menjadi kunci utama pelanggan.

MySQL 5.7.5 dan yang lebih baru menerapkan deteksi ketergantungan fungsional. Jika mode ONLY_FULL_GROUP_BY SQL diaktifkan (yang secara default), MySQL menolak kueri yang daftar pilihnya, kondisi HAVING, atau daftar ORDER BY merujuk ke kolom nonagregasi yang tidak dinamai dalam klausa GROUP BY juga tidak secara fungsional bergantung padanya .

melalui MySQL :: MySQL 5.7 Buku Petunjuk Referensi :: 12.19.3 Penanganan MySQL GROUP BY

Anda dapat mengatasinya dengan mengubah mode sql dengan perintah ini:

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

dan ... ingatlah untuk menyambungkan kembali database !!!

ElliotMok
sumber
5

buka phpmyadmin dan buka konsol dan jalankan permintaan ini

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
fajr abd el ali
sumber
4

Hai, alih-alih mengambil semua kolom, ambil saja apa yang Anda butuhkan dengan menggunakan ANY_VALUE(column_name) . Ini bekerja dengan sempurna. Cek saja.

Misalnya:

SELECT proof_type,any_value("customer_name") as customer_name
FROM `tbl_customer_pod_uploads`
WHERE `load_id` = '78' AND `status` = 'Active' GROUP BY `proof_type`
siva.picky
sumber
3

Cari "mode SQL" jika Anda menggunakan PhpMyAdmin dan hapus nilainya ONLY_FULL_GROUP_BY:, lakukan saja dan tidak masalah.

Mr_Bull
sumber
3
> sudo nano /etc/mysql/my.cnf

Masuk di bawah

[mysqld]
sql_mode = ""

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart
Sundar
sumber
2

Dari tampilannya, menurut saya pengelompokan berdasarkan beberapa kolom / bidang tidak akan merusak hasil Anda. Mengapa Anda tidak mencoba menambahkan ke grup dengan seperti ini:

GROUP BY `proof_type`, `id`

Ini akan dikelompokkan proof_typeterlebih dahulu id. Saya harap ini tidak mengubah hasil. Dalam beberapa / kebanyakan kasus, kelompok dengan beberapa kolom memberikan hasil yang salah.

jkkenzie.dll
sumber
1
  1. Masuk ke phpMyAdmin
  2. Arahkan ke: Server: localhost: 3306 dan jangan pilih database apa pun
  3. Klik variabel dari menu atas
  4. Telusuri "mode sql" dan edit nilai terkait ke: NO_ENGINE_SUBSTITUTION

Itu saja.

Saya melakukan ini di Ec2 saya dan itu bekerja seperti pesona.

PrafulPravin
sumber
1

Berikut ini cara yang sangat cepat dan mudah untuk mengaturnya secara permanen

NB: berjalan SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); bersifat sementara dan saat server restart Anda masih akan berakhir dengan kesalahan. Untuk memperbaikinya secara permanen lakukan hal di bawah ini

  1. Masuk ke server Anda sebagai root
  2. di terminal Anda wget https://gist.githubusercontent.com/nfourtythree/90fb8ef5eeafdf478f522720314c60bd/raw/disable-strict-mode.sh
  3. Jadikan skrip dapat dieksekusi dengan menjalankan chmod +x disable-strict-mode.sh
  4. Jalankan skrip dengan menjalankan ./disable-strict-mode.sh

Dan selesai, perubahan akan dilakukan pada mysql dan akan dimulai ulang

Nelson Bwogora
sumber
0

Pembaruan untuk MySQL 8.0

Anda sql-modetidak akan memilikinya NO_AUTO_CREATE_USERkarena telah dihapus seperti yang disebutkan di sini - how-to-set-sql-mode-in-my-cnf-in-mysql-8

[mysqld]
sql-mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

Juga jika seseorang tidak memiliki my.cnffile maka mereka membuat yang baru /etc/my.cnfdan kemudian menambahkan baris di atas.

Gautam
sumber
0

Saya memiliki masalah serupa dengan bagian dari penghancuran database saya. Yang saya lakukan adalah mengubah parameter di DB melalui konsol database PHPStorm seperti ini:

   SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

bekerja seperti pesona sekarang

Shoshinmas
sumber
-2

Di Anda my.ini, tulis ini:

[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

tergantung pada versi Anda. Atau:

[mysqld]
sql_mode = ""

atau cukup hapus ini: ONLY_FULL_GROUP_BY

Gary Carranza Sebastian
sumber
-2

Buka panel WAMP Anda dan buka file konfigurasi MySQL. Di dalamnya cari "sql_mode" jika Anda menemukannya setel ke "" lain jika Anda tidak menemukannya tambahkan sql_mode = "" ke file.

Mulai ulang server MySQL dan Anda siap melakukannya ...

selamat coding.

Mohd Samgan Khan
sumber