MySQL Cláusula GROUP BY y HAVING con ejemplos
⚡ Resumen inteligente
Las cláusulas SQL GROUP BY y HAVING convierten filas detalladas en informes resumidos. GROUP BY agrupa las filas que comparten los mismos valores en una sola fila por grupo, mientras que HAVING filtra esos grupos después de aplicar funciones de agregación como COUNT.

¿Qué es la cláusula GROUP BY de SQL?
La cláusula GROUP BY es un comando SQL que se utiliza para agrupar filas que tienen los mismos valoresSe escribe dentro de la instrucción SELECT y normalmente se utiliza junto con funciones de agregación para generar informes resumidos de la base de datos.
Eso es lo que hace: resume los datos almacenadas en la base de datos. Las consultas que contienen la cláusula GROUP BY se denominan consultas agrupadas y devuelven una sola fila por cada elemento agrupado.
GRUPO SQL POR Sintaxis
Ahora que el propósito de la cláusula está claro, veamos la sintaxis de una consulta agrupada básica.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
AQUÍ
- "Sentencias SELECT…” es el estándar SQL SELECT consulta de comando.
- "GRUPO POR nombre_columna1” es la cláusula que realiza el grupoping basado en column_name1.
- "[, nombre_columna2, …]” es opcional y representa otros nombres de columna cuando el grupoping se realiza en más de una columna.
- "[TENIENDO condición]” es opcional y se utiliza para restringir las filas afectadas por la cláusula GROUP BY. Es similar a la Dónde cláusula, excepto que se aplica después del sueloping.
Grouping Utilizando una sola columna
La forma más rápida de ver el efecto de la cláusula GROUP BY de SQL es comparar una consulta sin agrupar con una agrupada. Comience con una consulta simple que devuelva todas las entradas de género en la tabla de miembros.
SELECT `gender` FROM `members`;
| género |
|---|
| Mujer |
| Mujer |
| Hombre |
| Mujer |
| Hombre |
| Hombre |
| Hombre |
| Hombre |
| Hombre |
Se devuelven nueve filas y cada valor se repite. Supongamos que queremos los valores únicos para el género. La siguiente consulta añade la cláusula GROUP BY.
SELECT `gender` FROM `members` GROUP BY `gender`;
Ejecutando el script anterior en MySQL Banco de trabajo contra myflixdb nos da los siguientes resultados.
| género |
|---|
| Mujer |
| Hombre |
Tenga en cuenta que solo se han devuelto dos filas, ya que la tabla solo contiene dos tipos de género. La cláusula GROUP BY agrupó a todos los miembros "Masculinos" y devolvió una sola fila para ellos, e hizo lo mismo con los miembros "Femeninos".
Grouping Uso de varias columnas
Grouping La función GROUP BY, que utiliza una sola columna, suele ser demasiado imprecisa para un informe real. Agrupar por (GROUP BY) acepta una lista de columnas separadas por comas, y la combinación de sus valores define cada grupo.
Supongamos que queremos una lista de valores de category_id de películas y los años correspondientes en que se estrenaron. Observe primero el resultado de esta sencilla consulta.
SELECT `category_id`, `year_released` FROM `movies`;
| categoria ID | año_de lanzamiento |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
Las filas resaltadas muestran que el resultado contiene duplicados. Al ejecutar la misma consulta con GROUP BY, se eliminan.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Ejecutando el script anterior en MySQL Workbench, al trabajar con myflixdb, nos da los siguientes resultados que se muestran a continuación.
| categoria ID | año_de lanzamiento |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
La cláusula GROUP BY opera tanto en category_id como en year_released para identificar único filas. Las dos filas duplicadas para la categoría 6 en 2007 se fusionaron en una sola.
Regla de oro: Si el ID de categoría es el mismo pero el año de lanzamiento es diferente, la fila se considera única. Si el ID de categoría y el año de lanzamiento son iguales para más de una fila, se consideran duplicadas y solo se muestra una de ellas.
Grouping y funciones agregadas
Eliminar duplicados es útil, pero el verdadero poder de grouping aparece cuando se empareja con Funciones agregadas. Una función agregada calcula un valor para cada grupo: COUNT cuenta filas, SUM suma valores y AVGMIN y MAX describen el rango.
Supongamos que queremos obtener el número total de miembros masculinos y femeninos en la base de datos. El siguiente script lo hace.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Ejecutando el script anterior en MySQL Workbench contra myflixdb nos da los siguientes resultados.
| género | CONTAR(`número_de_miembro`) |
|---|---|
| Mujer | 3 |
| Hombre | 6 |
Las filas se agrupan según cada valor de género único, y la función de agregación COUNT cuenta el número de filas dentro de cada grupo. Los nueve registros de miembros se agrupan en dos filas de resumen.
Restringir los resultados de una consulta mediante la cláusula HAVING.
GroupingNo siempre se desean criterios específicos para cada fila de una tabla. A veces, el informe debe restringirse a un criterio determinado, y esa es la función de la cláusula HAVING.
Supongamos que queremos saber todos los años de lanzamiento de la película con ID de categoría 8. El siguiente script logra ese resultado.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Ejecutando el script anterior en MySQL Workbench, al trabajar con myflixdb, nos da los siguientes resultados que se muestran a continuación.
| id_película | título | director | año_de lanzamiento | categoria ID |
|---|---|---|---|---|
| 9 | Honey moonERS | Juan Schultz | 2005 | 8 |
| 5 | Las niñas de papá | NULL | 2007 | 8 |
Solo las películas con ID de categoría 8 se han conservado según la condición HAVING.
Advertencia: MySQL La versión 5.7 y posteriores habilitan el modo ONLY_FULL_GROUP_BY de forma predeterminada, y bajo ese modo, la instrucción SELECT * con una cláusula GROUP BY es rechazada, porque movie_id, title y director no están agrupados ni agregados. En producción, nombre explícitamente las columnas agrupadas, por ejemplo SELECCIONAR category_id, year_released DE películas AGRUPAR POR category_id, year_released TENIENDO category_id = 8;
WHERE vs HAVING vs GROUP BY vs ORDER BY
Los principiantes suelen mezclar estas cuatro cláusulas, porque todas ellas dan forma al conjunto de resultados. La diferencia radica en cuándo MySQL Aplica las siguientes reglas: WHERE se ejecuta antes de que se agrupen las filas, HAVING se ejecuta después y ORDER BY se ejecuta al final de todas.
| Cláusula | ¿Qué hace? | Cuando se ejecuta | Acepta funciones agregadas |
|---|---|---|---|
| Dónde | Filtra filas individuales antes de cualquier grupo.ping. | Antes de AGRUPAR POR | No |
| GRUPO POR | Agrupa las filas que comparten los mismos valores en una sola fila por grupo. | Después de DÓNDE | No es aplicable |
| TENIENDO | Filtra los grupos producidos por GROUP BY. | Después de AGRUPAR POR | Sí, por ejemplo HAVING COUNT(*) > 2 |
| ORDEN POR | Ordena las filas que sobreviven a las cláusulas anteriores. | Apellido | Sí, se puede ordenar un alias agregado. |
La consecuencia práctica es de rendimiento. Filtrar con WHERE elimina filas antes del grupo.ping El trabajo comienza, por lo que una condición que no depende de un resultado agregado pertenece a WHERE en lugar de HAVING.
