La liste SELECT n'est pas dans la clause GROUP BY et contient une colonne non agrégée… incompatible avec sql_mode = only_full_group_by

116

AM en utilisant MySQL 5.7.13 sur mon PC Windows avec WAMP Server

Voici mon problème lors de l'exécution de cette requête

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

Je reçois toujours une erreur comme celle-ci

L'expression n ° 1 de la liste SELECT n'est pas dans la clause GROUP BY et contient la colonne non agrégée 'returntr_prod.tbl_customer_pod_uploads.id' qui n'est pas fonctionnellement dépendante des colonnes de la clause GROUP BY; ceci est incompatible avec sql_mode = only_full_group_by

Pouvez-vous me dire la meilleure solution ...

J'ai besoin d'un résultat comme

+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
| 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
la source
12
N'utilisez pas SELECT *.
shmosel
disent comme ça SELECT id FROM tbl_customer_pod_uploadsWHERE load_id= '78' AND status= 'Active' GROUP BYproof_type
Dhanu K
2
Si vous souhaitez une compatibilité avec les anciennes requêtes, vous pouvez désactiver le only_full_group_bymode SQL.
Barmar
4
Essayez d'utiliser 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

Réponses:

229

Ce

L'expression n ° 1 de la liste SELECT n'est pas dans la clause GROUP BY et contient la colonne non agrégée 'returntr_prod.tbl_customer_pod_uploads.id' qui n'est pas fonctionnellement dépendante des colonnes de la clause GROUP BY; ceci est incompatible avec sql_mode = only_full_group_by

sera simplement résolu en changeant le mode sql dans MySQL par cette commande,

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

Cela fonctionne aussi pour moi .. J'ai utilisé ceci, car dans mon projet il y a beaucoup de requêtes comme celle-ci, donc j'ai juste changé ce mode sql en only_full_group_by

Je vous remercie... :-)

Dhanu K
la source
14
Ça marche pour moi!. Vous sauvez ma journée. N'oubliez pas de RESTART MYSQL SERVICE
marcode_ely
2
Si j'utilise codeigniter et que je souhaite exécuter dans le modèle, comment puis-je l'utiliser? Peut m'aider? @marcode_ely
DhavalThakor
@DhavalThakor, une fois que vous exécutez cette requête sur votre serveur, vous n'avez plus besoin de l'exécuter encore et encore. donc pas besoin de le mettre dans votre modèle
Dhanu K
2
MySQL 5.7.29, n'a pas besoin de redémarrer le service
Taavi
J'utilise la version du serveur: 5.7.31-0ubuntu0.16.04.1 - (Ubuntu), et chaque fois que je démarre ma machine, je la règle à chaque fois, y a-t-il un correctif permanent pour cela?
Arpita Hunka
71

Lorsque le only_full_group_bymode MySQL est activé, cela signifie que des règles SQL ANSI strictes s'appliqueront lors de l'utilisation GROUP BY. En ce qui concerne votre requête, cela signifie que si vous êtes GROUP BYde la proof_typecolonne, vous ne pouvez sélectionner que deux choses:

  • les proof_type colonne, ou
  • agrégats de toute autre colonne


Par « agrégats » d'autres colonnes, je veux dire en utilisant une fonction d' agrégation tels que MIN(), MAX()ou AVG()avec une autre colonne. Donc, dans votre cas, la requête suivante serait valide:

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 grande majorité de MySQL GROUP BY questions que je vois sur SO ont le mode strict désactivé, donc la requête est en cours d'exécution, mais avec des résultats incorrects. Dans votre cas, la requête ne s'exécutera pas du tout, vous obligeant à réfléchir à ce que vous voulez vraiment faire.

Remarque: Le SQL ANSI étend ce qui est autorisé à être sélectionné en GROUP BYincluant également des colonnes qui dépendent fonctionnellement de la ou des colonnes sélectionnées. Un exemple de dépendance fonctionnelle serait le regroupement par une colonne de clé primaire dans une table. Étant donné que la clé primaire est garantie d'être unique pour chaque enregistrement, la valeur de toute autre colonne serait également déterminée. MySQL est l'une des bases de données qui permet cela (SQL Server et Oracle n'AFAIK).

Tim Biegeleisen
la source
2
Juste une remarque: le résultat n'est pas incorrect (il suit les règles de MySQL), mais il est imprévisible, ce qui signifie que les colonnes ne faisant pas partie de group by et non agrégées (et non fonctionnellement dépendantes) renverront une valeur `` aléatoire '' du groupe correspondant. Comme l'indique le manuel: "le serveur est libre de choisir n'importe quelle valeur de chaque groupe"
Prédan
Le non-respect du regroupement strict ne produit pas nécessairement des résultats incorrects. Je le fais généralement lorsque les champs sont garantis identiques (par exemple, une jointure un-à-plusieurs). Et même si ce n'est pas garanti, sélectionner une ligne arbitraire ne sera souvent plus incorrecte que d'utiliser une fonction d'agrégation ou d'ajouter un niveau de regroupement.
shmosel le
1
+1 pour moi. Je n'ai aucune idée de la raison pour laquelle la réponse «acceptée» ci-dessus a été acceptée. Votre chemin est le bon chemin et la réponse acceptée est le correctif de piratage habituel qui entraînera plus de problèmes à l'avenir.
Jcov
1
@Jcov ... et je ne suis pas d'accord avec votre commentaire plus +1. La désactivation de la restriction ANSI GROUP BYest presque toujours une mauvaise idée. Cela me fait peur que tant d'utilisateurs prennent les mauvais conseils et les utilisent.
Tim Biegeleisen
1
@TimBiegeleisen Bienvenue dans le développement moderne du copier-coller. "Je n'ai pas besoin de réfléchir, quelqu'un qui a lu quelque chose au hasard à partir d'une source non fiable a déjà réfléchi pour moi".
Jcov
39

Utilisez n'importe quelle solution

(1) PHPMyAdmin

si vous utilisez phpMyAdmin, modifiez le paramètre " sql_mode " comme indiqué dans la capture d'écran ci-dessous. entrez la description de l'image ici

Modifiez la variable "mode sql" et supprimez le texte "ONLY_FULL_GROUP_BY" de la valeur

(2) Invite SQL / Commande Exécutez la commande ci-dessous.

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

(3) ** Ne pas utiliser SELECT ***

Utilisez la colonne appropriée dans la requête SELECT. pertinent signifie les colonnes, qui viennent soit dans la clause "group by", soit dans la colonne avec la fonction d'agrégation (MAX, MIN, SUM, COUNT, etc.)


Note importante

Les modifications apportées à l'aide du point (1) OU du point (2) ne le définiront pas de manière PERMANENTE et il reviendra après chaque redémarrage.

Vous devez donc définir ceci dans votre fichier de configuration (par exemple /etc/mysql/my.cnf dans la section [mysqld]), afin que les modifications restent en vigueur après le redémarrage de MySQL:

Fichier de configuration : /etc/mysql/my.cnf

Nom de la variable : sql_mode OU sql-mode

Rakesh Soni
la source
19

La méthode ci-dessous a résolu mon problème:

Dans ubuntu

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

tapez A pour entrer en mode insertion

Dans la dernière ligne, collez sous le code de deux lignes:

[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

Tapez esc pour quitter le mode d'entrée

Type :wq to save and close vim.

Tapez sudo service mysql restartpour redémarrer MySQL.

Anand Huded
la source
1
merci, cela a fonctionné! dans cent os, whm, my.cnf était situé dans sudo vi /etc/my.cnf
Reejesh PK
17

Vous pouvez désactiver sql_mode = only_full_group_by par une commande, vous pouvez essayer cela par terminal ou 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
la source
10

Dans Ubuntu

Étape 1:

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

Étape 2: allez à la dernière ligne et ajoutez ce qui suit

sql_mode = ""

Étape 3: Enregistrer

Étape 4: Redémarrez le serveur mysql.

Gullu Mutullu
la source
9

Pour que la requête soit légale dans SQL92, la colonne de nom doit être omise de la liste de sélection ou nommée dans la clause GROUP BY.

SQL99 et les versions ultérieures autorisent ces non-agrégats par fonction optionnelle T301 s'ils dépendent fonctionnellement des colonnes GROUP BY: Si une telle relation existe entre le nom et le dépositaire, la requête est légale. Ce serait le cas, par exemple, si custid était une clé primaire de clients.

MySQL 5.7.5 et versions ultérieures implémente la détection de la dépendance fonctionnelle. Si le mode SQL ONLY_FULL_GROUP_BY est activé (ce qui est le cas par défaut), MySQL rejette les requêtes pour lesquelles la liste de sélection, la condition HAVING ou la liste ORDER BY font référence à des colonnes non agrégées qui ne sont ni nommées dans la clause GROUP BY ni en dépendent fonctionnellement .

via MySQL :: MySQL 5.7 Reference Manual :: 12.19.3 Gestion MySQL de GROUP BY

Vous pouvez le résoudre en changeant le mode sql avec cette commande:

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

et ... pensez à reconnecter la base de données !!!

ElliotMok
la source
5

allez dans le phpmyadmin et ouvrez la console et exécutez cette requête

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
fajr abd el ali
la source
3

Recherchez "SQL mode" si vous utilisez PhpMyAdmin et retirez la valeur:, ONLY_FULL_GROUP_BYjuste fait et ça va.

Mr_Bull
la source
2

De son apparence, je pense que le regroupement par plusieurs colonnes / champs ne nuira pas à votre résultat. Pourquoi n'essayez-vous pas d'ajouter au groupe comme ceci:

GROUP BY `proof_type`, `id`

Cela regroupera d' proof_typeabord ensuite id. J'espère que cela ne modifie pas les résultats. Dans certains / la plupart des cas, le regroupement par plusieurs colonnes donne des résultats erronés.

jkkenzie
la source
2
> sudo nano /etc/mysql/my.cnf

Entrez ci-dessous

[mysqld]
sql_mode = ""

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart
Sundar
la source
2

Salut au lieu de prendre toutes les colonnes, prenez simplement ce dont vous avez besoin en utilisant ANY_VALUE(column_name). Cela fonctionne parfaitement. Vérifiez simplement.

Par exemple:

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
la source
1
  1. Connectez-vous à phpMyAdmin
  2. Accédez à: Serveur: localhost: 3306 et ne sélectionnez aucune base de données
  3. Cliquez sur les variables dans le menu supérieur
  4. Recherchez "sql mode" et modifiez la valeur correspondante en: NO_ENGINE_SUBSTITUTION

C'est tout.

Je l'ai fait dans mon Ec2 et cela a fonctionné comme du charme.

PrafulPravin
la source
1

Voici un moyen très rapide et simple de le configurer de manière permanente

NB: l'exécution SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); est temporaire et au redémarrage du serveur, vous vous retrouverez toujours avec l'erreur. Pour résoudre ce problème de manière permanente, procédez comme suit

  1. Connectez-vous à votre serveur en tant que root
  2. dans votre terminal run wget https://gist.githubusercontent.com/nfourtythree/90fb8ef5eeafdf478f522720314c60bd/raw/disable-strict-mode.sh
  3. Rendre le script exécutable en exécutant chmod +x disable-strict-mode.sh
  4. Exécutez le script en exécutant ./disable-strict-mode.sh

Et vous avez terminé, des modifications seront apportées à mysql et il sera redémarré

Nelson Bwogora
la source
0

Mise à jour pour MySQL 8.0

Votre sql-moden'aura pas NO_AUTO_CREATE_USERcomme il a été supprimé comme mentionné ici - comment-définir-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"

De plus, si quelqu'un n'a pas de my.cnffichier, il en crée un nouveau /etc/my.cnfet ajoute les lignes ci-dessus.

Gautam
la source
-2

Dans votre my.ini, écrivez ceci:

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

dépendent de votre version. Ou:

[mysqld]
sql_mode = ""

ou supprimez simplement ceci: ONLY_FULL_GROUP_BY

Gary Carranza Sebastian
la source
-2

Ouvrez votre panneau WAMP et ouvrez le fichier de configuration MySQL. Dans celui-ci, recherchez "sql_mode" si vous le trouvez, réglez-le sur "" sinon si vous ne le trouvez pas, ajoutez sql_mode = "" au fichier.

Redémarrez le serveur MySQL et vous êtes prêt à partir ...

bon codage.

Mohd Samgan Khan
la source