La lista SELECT no está en la cláusula GROUP BY y contiene una columna no agregada… incompatible con sql_mode = only_full_group_by

116

Estoy usando MySQL 5.7.13 en mi PC con Windows con WAMP Server

Aquí mi problema es al ejecutar esta consulta

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

Siempre recibo un error como este

La expresión # 1 de la lista SELECT no está en la cláusula GROUP BY y contiene la columna no agregada 'returntr_prod.tbl_customer_pod_uploads.id' que no depende funcionalmente de las columnas de la cláusula GROUP BY; esto es incompatible con sql_mode = only_full_group_by

¿Puedes decirme cuál es la mejor solución?

Necesito un resultado como

+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
| 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
fuente
12
No lo use SELECT *.
shmosel
están diciendo así SELECT id FROM tbl_customer_pod_uploadsWHERE load_id= '78' AND status= 'Active' GROUP BYproof_type
Dhanu K
2
Si desea compatibilidad con consultas antiguas, puede desactivar el only_full_group_bymodo SQL.
Barmar
4
Intente usar 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

Respuestas:

229

Esta

La expresión # 1 de la lista SELECT no está en la cláusula GROUP BY y contiene la columna no agregada 'returntr_prod.tbl_customer_pod_uploads.id' que no depende funcionalmente de las columnas de la cláusula GROUP BY; esto es incompatible con sql_mode = only_full_group_by

se resolverá simplemente cambiando el modo sql en MySQL con este comando,

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

Esto también funciona para mí. Usé esto, porque en mi proyecto hay muchas consultas como esta, así que acabo de cambiar este modo sql a only_full_group_by

Gracias... :-)

Dhanu K
fuente
14
¡Esto funciona para mi!. Salvas mi día. Recuerde REINICIAR EL SERVICIO MYSQL
marcode_ely
2
Si estoy usando codeigniter y quiero ejecutar en el modelo, ¿cómo lo usaría? Puede ayudarme ? @marcode_ely
DhavalThakor
@DhavalThakor, una vez que ejecuta esta consulta en su servidor, no necesita ejecutarla una y otra vez. por lo que no es necesario que lo pongas en tu modelo
Dhanu K
2
MySQL 5.7.29, no es necesario reiniciar el servicio
Taavi
Estoy usando la versión del servidor: 5.7.31-0ubuntu0.16.04.1 - (Ubuntu), y cada vez que inicio mi máquina, la configuro cada vez, ¿hay alguna solución permanente para esto?
Arpita Hunka
71

Cuando el only_full_group_bymodo de MySQL está activado, significa que se aplicarán reglas estrictas de ANSI SQL al usar GROUP BY. Con respecto a su consulta, esto significa que si pertenece GROUP BYa la proof_typecolumna, solo puede seleccionar dos cosas:

  • el proof_type columna, o
  • agregados de cualquier otra columna


Por "agregados" de otras columnas, me refiero a usar una función de agregado como MIN(), MAX()o AVG()con otra columna. Entonces, en su caso, la siguiente consulta sería válida:

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 gran mayoría de MySQL GROUP BY preguntas que veo en SO tienen el modo estricto desactivado, por lo que la consulta se está ejecutando, pero con resultados incorrectos. En su caso, la consulta no se ejecutará en absoluto, lo que le obligará a pensar en lo que realmente quiere hacer.

Nota: ANSI SQL amplía lo que se permite seleccionar GROUP BYal incluir también columnas que dependen funcionalmente de la (s) columna (s) que se seleccionan. Un ejemplo de dependencia funcional sería agrupar por una columna de clave principal en una tabla. Dado que se garantiza que la clave principal es única para cada registro, también se determinaría el valor de cualquier otra columna. MySQL es una de las bases de datos que permite esto (SQL Server y Oracle no lo hacen AFAIK).

Tim Biegeleisen
fuente
2
Solo una nota: el resultado no es incorrecto (sigue las reglas de MySQL), pero es impredecible, es decir, las columnas que no forman parte del grupo por y no agregadas (y no funcionalmente dependientes) devolverán un valor 'aleatorio' del grupo correspondiente. Como dice el manual: "el servidor es libre de elegir cualquier valor de cada grupo"
Pred
Violar la agrupación estricta no necesariamente produce resultados incorrectos. Normalmente lo hago cuando se garantiza que los campos son idénticos (por ejemplo, una combinación de uno a varios). E incluso si no está garantizado, seleccionar una fila arbitraria a menudo no será más incorrecto que usar una función agregada o agregar un nivel de agrupación.
shmosel
1
+1 para mí. No tengo idea de por qué se ha aceptado la respuesta "aceptada" anterior. Su camino es el camino correcto y la respuesta aceptada es la solución hacky habitual que dará lugar a más problemas en el futuro.
Jcov
1
@Jcov ... y no podría estar de acuerdo con tu comentario más +1. Desactivar la restricción ANSI GROUP BYes casi siempre una mala idea. Me asusta que tantos usuarios sigan un consejo equivocado y lo utilicen.
Tim Biegeleisen
1
@TimBiegeleisen bienvenido al desarrollo moderno de copiar y pegar. "No necesito pensar, alguien que ha leído algo al azar en algún lugar de una fuente poco confiable ya ha pensado por mí".
Jcov
39

Utilice cualquier solución

(1) PHPMyAdmin

Si está utilizando phpMyAdmin, cambie la configuración de " sql_mode " como se menciona en la siguiente captura de pantalla. ingrese la descripción de la imagen aquí

Edite la variable "modo sql" y elimine el texto "ONLY_FULL_GROUP_BY" del valor

(2) Símbolo del sistema / SQL Ejecute el siguiente comando.

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

(3) ** No use SELECT ***

Utilice la columna relevante en la consulta SELECT. columnas de medios relevantes, que vienen en la cláusula "agrupar por" o en la columna con la función agregada (MAX, MIN, SUM, COUNT, etc.)


Nota IMPORTANTE

Los cambios realizados utilizando el punto (1) O el punto (2) no lo configurarán PERMANENTEMENTE, y se revertirá después de cada reinicio.

Por lo tanto, debe establecer esto en su archivo de configuración (por ejemplo, /etc/mysql/my.cnf en la sección [mysqld]), para que los cambios sigan vigentes después de reiniciar MySQL:

Archivo de configuración : /etc/mysql/my.cnf

Nombre de la variable : sql_mode O sql-mode

Rakesh Soni
fuente
19

El siguiente método resolvió mi problema:

En ubuntu

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

escriba A para ingresar al modo de inserción

En la última línea, pegue el código de dos líneas a continuación:

[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

Escriba esc para salir del modo de entrada

Type :wq to save and close vim.

Escriba sudo service mysql restartpara reiniciar MySQL.

Anand Huded
fuente
1
gracias, funcionó! en cent os, whm, my.cnf estaba ubicado en sudo vi /etc/my.cnf
Reejesh PK
17

Puede deshabilitar sql_mode = only_full_group_by mediante algún comando, puede intentarlo mediante terminal 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';
Anil Gupta
fuente
10

En Ubuntu

Paso 1:

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

Paso 2: Vaya a la última línea y agregue lo siguiente

sql_mode = ""

Paso 3: guardar

Paso 4: reinicie el servidor mysql.

Gullu Mutullu
fuente
9

Para que la consulta sea legal en SQL92, la columna de nombre debe omitirse de la lista de selección o nombrarse en la cláusula GROUP BY.

SQL99 y posteriores permiten tales no agregados por característica opcional T301 si son funcionalmente dependientes de las columnas GROUP BY: Si existe tal relación entre el nombre y el custid, la consulta es legal. Este sería el caso, por ejemplo, si fuera una clave primaria de los clientes.

MySQL 5.7.5 y versiones posteriores implementan la detección de dependencia funcional. Si el modo SQL ONLY_FULL_GROUP_BY está habilitado (que es por defecto), MySQL rechaza las consultas para las cuales la lista de selección, la condición HAVING o la lista ORDER BY se refieren a columnas no agregadas que no están nombradas en la cláusula GROUP BY ni son funcionalmente dependientes de ellas .

a través de MySQL :: MySQL 5.7 Reference Manual :: 12.19.3 Manejo MySQL de GROUP BY

Puede resolverlo cambiando el modo sql con este comando:

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

y ... recuerda volver a conectar la base de datos !!!

ElliotMok
fuente
5

vaya a phpmyadmin y abra la consola y ejecute esta solicitud

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

Busque "modo SQL" si está utilizando PhpMyAdmin y quite el valor:, ONLY_FULL_GROUP_BYsimplemente lo hizo y está bien.

Mr_Bull
fuente
2

Por cómo se ve, creo que agrupar por múltiples columnas / campos no dañará su resultado. ¿Por qué no intentas agregar al grupo de esta manera:

GROUP BY `proof_type`, `id`

Esto se agrupará proof_typeprimero y luego id. Espero que esto no altere los resultados. En algunos / la mayoría de los casos, el grupo por varias columnas da resultados incorrectos.

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

Ingrese abajo

[mysqld]
sql_mode = ""

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart
Sundar
fuente
2

Hola, en lugar de tomar todas las columnas, solo tome lo que necesita usando ANY_VALUE(column_name). Funciona perfectamente. Sólo revisa.

P.ej:

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
fuente
1
  1. Inicie sesión en phpMyAdmin
  2. Navegue a: Server: localhost: 3306 y no seleccione ninguna base de datos
  3. Haga clic en las variables del menú superior
  4. Busque "modo sql" y edite el valor correspondiente a: NO_ENGINE_SUBSTITUTION

Eso es todo.

Hice esto en mi Ec2 y funcionó a las mil maravillas.

PrafulPravin
fuente
1

Aquí hay una forma realmente rápida y fácil de configurarlo permanentemente

NB: la ejecución SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); es temporal y, al reiniciar el servidor, aún terminará con el error. Para solucionar este problema de forma permanente, haga lo siguiente

  1. Inicie sesión en su servidor como root
  2. en tu terminal ejecutar wget https://gist.githubusercontent.com/nfourtythree/90fb8ef5eeafdf478f522720314c60bd/raw/disable-strict-mode.sh
  3. Haga que el script sea ejecutable ejecutando chmod +x disable-strict-mode.sh
  4. Ejecute el script ejecutando ./disable-strict-mode.sh

Y listo, se realizarán cambios en mysql y se reiniciará

Nelson Bwogora
fuente
0

Actualización para MySQL 8.0

No sql-modelo tendrá, NO_AUTO_CREATE_USERya que se eliminó como se menciona aquí: cómo-establecer-modo-sql-en-mi-cnf-en-mysql-8

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

Además, si alguien no tiene un my.cnfarchivo, crea uno nuevo /etc/my.cnfy luego agrega las líneas anteriores.

Gautama
fuente
-2

En tu my.ini, escribe esto:

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

depende de su versión. O:

[mysqld]
sql_mode = ""

o simplemente elimine esto: ONLY_FULL_GROUP_BY

Gary Carranza Sebastián
fuente
-2

Abra su panel WAMP y abra el archivo de configuración de MySQL. En él, busque "sql_mode" si lo encuentra, configúrelo en ""; de lo contrario, si no lo encuentra, agregue sql_mode = "" al archivo.

Reinicie el servidor MySQL y estará listo ...

codificación feliz.

Mohd Samgan Khan
fuente