L'elenco SELECT non è nella clausola GROUP BY e contiene una colonna non aggregata ... incompatibile con sql_mode = only_full_group_by


116

Sto usando MySQL 5.7.13 sul mio PC Windows con WAMP Server

Qui il mio problema è durante l'esecuzione di questa query

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

Ricevo sempre un errore come questo

L'espressione n. 1 dell'elenco SELECT non è nella clausola GROUP BY e contiene la colonna non aggregata "returntr_prod.tbl_customer_pod_uploads.id" che non è funzionalmente dipendente dalle colonne nella clausola GROUP BY; questo non è compatibile con sql_mode = only_full_group_by

Puoi dirmi la soluzione migliore ...

Ho bisogno di un risultato simile

+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
| 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 |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+

12
Non usare SELECT *.
shmosel


stanno dicendo in questo modo SELECT id FROM tbl_customer_pod_uploadsWHERE load_id= '78' AND status= 'Active' GROUP BYproof_type
Dhanu K

2
Se desideri la compatibilità per le vecchie query, puoi disattivare la only_full_group_bymodalità SQL.
Barmar

4
Prova a utilizzare 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

Risposte:


229

Questo

L'espressione n. 1 dell'elenco SELECT non è nella clausola GROUP BY e contiene la colonna non aggregata "returntr_prod.tbl_customer_pod_uploads.id" che non è funzionalmente dipendente dalle colonne nella clausola GROUP BY; questo non è compatibile con sql_mode = only_full_group_by

sarà semplicemente risolto cambiando la modalità sql in MySQL con questo comando,

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

Anche questo funziona per me .. Ho usato questo, perché nel mio progetto ci sono molte query come questa quindi ho cambiato questa modalità sql in only_full_group_by

Grazie... :-)


14
Per me funziona!. Mi salvi la giornata. Ricordati di RIAVVIARE IL SERVIZIO MYSQL
marcode_ely

2
Se sto usando codeigniter e voglio eseguire in model, come lo userei? Puoi aiutarmi ? @marcode_ely
DhavalThakor

@DhavalThakor, una volta eseguita questa query nel server, non è necessario eseguirla più e più volte. quindi non è necessario inserirlo nel modello
Dhanu K

2
MySQL 5.7.29, non ha bisogno di riavviare il servizio
Taavi

Sto usando la versione server: 5.7.31-0ubuntu0.16.04.1 - (Ubuntu), e ogni volta che avvio la mia macchina, la imposto ogni volta. C'è qualche soluzione permanente per questo?
Arpita Hunka

71

Quando la only_full_group_bymodalità di MySQL è attiva, significa che verranno applicate le rigide regole ANSI SQL durante l'utilizzo GROUP BY. Per quanto riguarda la tua query, questo significa che se sei GROUP BYdella proof_typecolonna, puoi selezionare solo due cose:

  • il proof_type colonna, o
  • aggregati di qualsiasi altra colonna


Da "aggregati" di altre colonne, intendo utilizzando una funzione di aggregazione come MIN(), MAX()o AVG()con un'altra colonna. Quindi nel tuo caso sarebbe valida la seguente query:

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

La stragrande maggioranza delle GROUP BYdomande MySQL che vedo su SO ha la modalità rigorosa disattivata, quindi la query è in esecuzione, ma con risultati errati. Nel tuo caso, la query non verrà eseguita affatto, costringendoti a pensare a ciò che vuoi veramente fare.

Nota: ANSI SQL estende ciò che è consentito selezionare GROUP BYincludendo anche colonne che dipendono dal punto di vista funzionale dalla colonna o dalle colonne selezionate. Un esempio di dipendenza funzionale sarebbe il raggruppamento in base a una colonna chiave primaria in una tabella. Poiché la chiave primaria è garantita come univoca per ogni record, verrebbe determinato anche il valore di qualsiasi altra colonna. MySQL è uno dei database che lo consente (SQL Server e Oracle non lo ritengono opportuno).


2
Solo una nota: il risultato non è errato (segue le regole di MySQL), ma è imprevedibile, il che significa che le colonne che non fanno parte del gruppo e non aggregate (e non funzionalmente dipendenti) restituiranno un valore "casuale" dal gruppo corrispondente. Come afferma il manuale: "il server è libero di scegliere qualsiasi valore da ciascun gruppo"
Pred

La violazione del raggruppamento rigoroso non produce necessariamente risultati errati. Di solito lo faccio quando è garantito che i campi sono identici (ad esempio un join uno-a-molti). E anche se non è garantito, la selezione di una riga arbitraria spesso non sarà più errata dell'utilizzo di una funzione aggregata o dell'aggiunta di un livello di raggruppamento.
shmosel

1
+1 per me. Non ho idea del motivo per cui la risposta "accettata" sopra sia stata accettata. La tua strada è quella corretta e la risposta accettata è la solita soluzione hacky che porterà a più problemi in futuro.
Jcov

1
@Jcov ... e non potrei essere d'accordo con il tuo commento più +1. Disattivare la restrizione ANSI GROUP BYè quasi sempre una cattiva idea. Mi spaventa che così tanti utenti prendano il consiglio sbagliato e lo utilizzino.
Tim Biegeleisen

1
@TimBiegeleisen benvenuto nel moderno sviluppo copia + incolla. "Non ho bisogno di pensare, qualcuno che ha letto una cosa casuale da qualche parte da una fonte inaffidabile ha già pensato per me".
Jcov

38

Usa una soluzione qualsiasi

(1) PHPMyAdmin

se stai usando phpMyAdmin, modifica l' impostazione " sql_mode " come indicato nello screenshot qui sotto. inserisci qui la descrizione dell'immagine

Modifica la variabile "modalità sql" e rimuovi il testo "ONLY_FULL_GROUP_BY" dal valore

(2) SQL / prompt dei comandi Eseguire il comando seguente.

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

(3) ** Non utilizzare SELEZIONA ***

Usa la colonna pertinente nella query SELECT. pertinente indica le colonne, che entrano nella clausola "group by" o nella colonna con la funzione di aggregazione (MAX, MIN, SUM, COUNT ecc.)


Nota importante

Le modifiche apportate utilizzando il punto (1) OPPURE il punto (2) non lo imposteranno PERMANENTEMENTE e verranno ripristinate dopo ogni riavvio.

Quindi dovresti impostarlo nel tuo file di configurazione (ad esempio /etc/mysql/my.cnf nella sezione [mysqld]), in modo che le modifiche rimangano attive dopo il riavvio di MySQL:

File di configurazione : /etc/mysql/my.cnf

Nome variabile : sql_mode O sql-mode


19

Il metodo seguente ha risolto il mio problema:

In ubuntu

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

digitare A per accedere alla modalità di inserimento

Nell'ultima riga incolla sotto il codice di due righe:

[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

Digita esc per uscire dalla modalità di immissione

Type :wq to save and close vim.

Digita sudo service mysql restartper riavviare MySQL.


1
grazie, ha funzionato! in cent os, whm, my.cnf si trovava su sudo vi /etc/my.cnf
Reejesh PK

17

Puoi disabilitare sql_mode = only_full_group_by con qualche comando puoi provare questo da terminale o 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';

10

In Ubuntu

Passo 1:

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

Passaggio 2: vai all'ultima riga e aggiungi quanto segue

sql_mode = ""

Passaggio 3: salva

Passaggio 4: riavvia il server mysql.


9

Affinché la query sia valida in SQL92, la colonna del nome deve essere omessa dall'elenco di selezione o denominata nella clausola GROUP BY.

SQL99 e versioni successive consentono tali non aggregati per funzionalità opzionale T301 se sono funzionalmente dipendenti dalle colonne GROUP BY: Se esiste una relazione di questo tipo tra nome e custid, la query è legale. Questo sarebbe il caso, ad esempio, se il cliente fosse una chiave primaria.

MySQL 5.7.5 e versioni successive implementa il rilevamento della dipendenza funzionale. Se la modalità SQL ONLY_FULL_GROUP_BY è abilitata (che è per impostazione predefinita), MySQL rifiuta le query per le quali l'elenco di selezione, la condizione HAVING o l'elenco ORDER BY si riferiscono a colonne non aggregate che non sono né nominate nella clausola GROUP BY né sono funzionalmente dipendenti da esse .

tramite MySQL :: MySQL 5.7 Manuale di riferimento :: 12.19.3 Gestione MySQL di GROUP BY

Puoi risolverlo cambiando la modalità sql con questo comando:

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

e ... ricordati di ricollegare il database !!!


5

vai al phpmyadmin e apri la console ed esegui questa richiesta

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

3

Cerca "modalità SQL" se stai usando PhpMyAdmin e togli il valore:, ONLY_FULL_GROUP_BYappena fatto e va bene.


2

Da come appare, penso che il raggruppamento per più colonne / campi non danneggerà il tuo risultato. Perché non provi ad aggiungere al gruppo in questo modo:

GROUP BY `proof_type`, `id`

Questo raggrupperà per proof_typeprimo quindi id. Spero che questo non modifichi i risultati. In alcuni / nella maggior parte dei casi, il raggruppamento per più colonne dà risultati errati.


2
> sudo nano /etc/mysql/my.cnf

Entra di seguito

[mysqld]
sql_mode = ""

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart

2

Ciao invece di prendere tutte le colonne, prendi quello che ti serve usando ANY_VALUE(column_name). Funziona perfettamente. Controlla solamente.

Per esempio:

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`

1
  1. Accedi a phpMyAdmin
  2. Vai a: Server: localhost: 3306 e non selezionare alcun database
  3. Fare clic sulle variabili dal menu in alto
  4. Cerca "modalità sql" e modifica il valore corrispondente in: NO_ENGINE_SUBSTITUTION

È tutto.

L'ho fatto nel mio Ec2 e ha funzionato a meraviglia.


1

Ecco un modo semplice e veloce per impostarlo in modo permanente

NB: l'esecuzione SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); è temporanea e al riavvio del server ti ritroverai comunque con l'errore. Per risolvere questo problema in modo permanente, procedi come segue

  1. Accedi al tuo server come root
  2. nel tuo terminale run wget https://gist.githubusercontent.com/nfourtythree/90fb8ef5eeafdf478f522720314c60bd/raw/disable-strict-mode.sh
  3. Rendi eseguibile lo script eseguendo chmod +x disable-strict-mode.sh
  4. Esegui lo script eseguendo ./disable-strict-mode.sh

E fatto, verranno apportate modifiche a mysql e verrà riavviato


0

Aggiornamento per MySQL 8.0

Il tuo sql-modenon avrà NO_AUTO_CREATE_USERcome è stato rimosso come menzionato qui - 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"

Inoltre, se qualcuno non ha un my.cnffile, ne crea uno nuovo /etc/my.cnfe poi aggiunge le righe sopra.


-2

Nel tuo my.ini, scrivi questo:

[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"

dipende dalla tua versione. O:

[mysqld]
sql_mode = ""

o semplicemente rimuovilo: ONLY_FULL_GROUP_BY


-2

Apri il tuo pannello WAMP e apri il file di configurazione di MySQL. In esso cerca "sql_mode" se lo trovi impostalo su "" altrimenti se non lo trovi aggiungi sql_mode = "" al file.

Riavvia il server MySQL e sei a posto ...

codifica felice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.