MySQL :: Manual de referencia de MySQL 5.6 :: 12.19.3 Manejo MySQL del GRUPO POR
12.19.3 Manejo MySQL del GRUPO POR
En SQL estándar, una consulta que incluye una cláusula GROUP BY
no puede hacer referencia a columnas no agregadas en la lista de selección que no se nombran en la cláusula GROUP BY
. Por ejemplo, esta consulta es ilegal en SQL estándar porque la columna no agregada name
de la lista de selección no aparece en GROUP BY
:
SELECT o.custid, c.name, MAX(o.payment) FROM orders AS o, customers AS c WHERE o.custid = c.custid GROUP BY o.custid;
Para que la consulta sea legal, el name
columna debe ser omitido de la lista de selección o nombrado en el GROUP BY
cláusula.
MySQL amplía el uso SQL estándar de GROUP BY
para que la lista de selección pueda hacer referencia a columnas no agregadas sin nombre en la cláusula GROUP BY
. Esto significa que la consulta anterior es legal en MySQL. Puede usar esta función para obtener un mejor rendimiento al evitar la clasificación y agrupación de columnas innecesarias. Sin embargo, esto es útil principalmente cuando todos los valores de cada columna no agregada no nombrada en GROUP BY
son los mismos para cada grupo. El servidor es libre de elegir cualquier valor de cada grupo, por lo que, a menos que sean los mismos, los valores elegidos no son deterministas. Además, no se puede influir en la selección de valores de cada grupo añadiendo una cláusula ORDER BY
. La ordenación del conjunto de resultados se produce después de que se hayan elegido los valores, y ORDER BY
no afecta a los valores de cada grupo que elija el servidor.
Una extensión MySQL similar se aplica a la cláusula HAVING
. En SQL estándar, una consulta no puede hacer referencia a columnas no agregadas de la cláusula HAVING
que no tengan nombre en la cláusula GROUP BY
. Para simplificar los cálculos, una extensión MySQL permite referencias a dichas columnas. Esta extensión asume que las columnas no agrupadas tienen los mismos valores de grupo. De lo contrario, el resultado es no determinista.
Para deshabilitar la extensión MySQL GROUP BY
y habilitar el comportamiento SQL estándar, habilite el modo SQL ONLY_FULL_GROUP_BY
. En este caso, las columnas no nombradas en la cláusula GROUP BY
no se pueden usar en la lista de selección o en la cláusula HAVING
a menos que estén encerradas en una función agregada.
La extensión de lista de selección también se aplica a ORDER BY
. Es decir, puede hacer referencia a columnas no agregadas en la cláusula ORDER BY
que no aparecen en la cláusula GROUP BY
. (Sin embargo, como se mencionó anteriormente, ORDER BY
no afecta qué valores se eligen de columnas no agregadas; solo los ordena después de que se han elegido.) Esta extensión no se aplica si el modo SQL ONLY_FULL_GROUP_BY
está habilitado.
Si una consulta tiene funciones agregadas y no tiene la cláusula GROUP BY
, no puede tener columnas no agregadas en la lista de selección, HAVING
condición, o ORDER BY
lista con ONLY_FULL_GROUP_BY
habilitado:
mysql> SELECT name, MAX(age) FROM t;ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)with no GROUP columns is illegal if there is no GROUP BY clause
Sin GROUP BY
, hay un solo grupo y no es determinista que name
valor a elegir por el grupo.
Otra extensión MySQL para SQL estándar permite referencias en la cláusula HAVING
a expresiones con alias en la lista de selección. Habilitar ONLY_FULL_GROUP_BY
evita esto. Por ejemplo, la siguiente consulta devuelve name
valores que solo aparecen una vez en la tabla orders
; la consulta es aceptada, independientemente de si ONLY_FULL_GROUP_BY
está habilitado:
SELECT name, COUNT(name) FROM orders GROUP BY name HAVING COUNT(name) = 1;
La siguiente consulta es aceptada sólo si ONLY_FULL_GROUP_BY
está deshabilitada.
SELECT name, COUNT(name) AS c FROM orders GROUP BY name HAVING c = 1;
Si está intentando seguir SQL estándar, solo puede usar expresiones de columna en las cláusulas GROUP BY
. Como solución alternativa, use un alias para la expresión:
SELECT id, FLOOR(value/100) AS val FROM tbl_name GROUP BY id, val;
MySQL permite expresiones sin columnas en cláusulas GROUP BY
, por lo que el alias es innecesario:
SELECT id, FLOOR(value/100) FROM tbl_name GROUP BY id, FLOOR(value/100);
Leave a Reply