Agrupación: la cláusula GROUP BY

Vamos a ejecutar una consulta:

MySQL 8.4
SELECT id, home_type, has_tv, price FROM Rooms;
idhome_typehas_tvprice
1Private room1149
2Entire home/apt0225
3Private room1150
4Entire home/apt189
5Entire home/apt080
6Entire home/apt0200
7Private room060
8Private room179
9Private room179
10Entire home/apt1150
11Entire home/apt1135
12Private room085
13Private room089
14Private room085
15Entire home/apt1120
40Shared room140
idhome_typehas_tvprice
1Private roomtrue149
2Entire home/aptfalse225
3Private roomtrue150
4Entire home/apttrue89
5Entire home/aptfalse80
6Entire home/aptfalse200
7Private roomfalse60
8Private roomtrue79
9Private roomtrue79
10Entire home/apttrue150
11Entire home/apttrue135
12Private roomfalse85
13Private roomfalse89
14Private roomfalse85
15Entire home/apttrue120
40Shared roomtrue40

Así obtenemos información de cada alojamiento en alquiler. Pero ¿y si no queremos información de cada registro por separado, sino de los grupos que forman?

Por ejemplo, esos grupos pueden ser los registros divididos por tipo de alojamiento:

  • Shared room (habitación compartida entre varias personas)
  • Private room (habitación privada entera)
  • Entire home/apt (piso completo)

Estos grupos incluyen registros distintos de la tabla y, por tanto, tienen características diferentes que nos pueden resultar muy útiles.

Esa información útil sobre los grupos puede ser:

  • el precio medio del alquiler de una habitación o de un alojamiento completo
  • el número de alojamientos en alquiler de cada tipo

Para responder a estas y muchas otras preguntas existe la cláusula GROUP BY.

Estructura general de una consulta con GROUP BY

MySQL 8.4
SELECT { literal | funcion_agregacion | campo_agrupacion } [, ...]
FROM nombre_tabla
GROUP BY campo_agrupacion [, ...];
  • [ ]parte opcional
  • { a | b }una de las opciones
  • ...se puede repetir
literal

Un valor fijo, por ejemplo 'text' o 1. Es el mismo para todos los grupos.

funcion_agregacion

Una función que calcula un único valor a partir de todas las filas del grupo, por ejemplo AVG(price).

campo_agrupacion

La columna por la que las filas se dividen en grupos: las filas con el mismo valor acaban en el mismo grupo. Puedes indicar varias columnas separadas por comas.

nombre_tabla
La tabla cuyas filas se agrupan.

Para que los registros formen grupos por tipo de alojamiento, después de GROUP BY tenemos que indicar home_type, es decir, la columna por la que se va a agrupar.

MySQL 8.4
SELECT home_type FROM Rooms
GROUP BY home_type
home_type
Private room
Entire home/apt
Shared room

Al usar la cláusula GROUP BY pasamos de trabajar con registros individuales a trabajar con los grupos que se han formado. Por eso ya no podemos mostrar sin más cualquier columna de la fila (por ejemplo, has_tv o price), como hacíamos antes. Y es que cada grupo puede contener varios registros, y cada uno de ellos puede tener un valor distinto en esa columna.

Con GROUP BY solo puedes mostrar:

  • literales, es decir, valores fijos indicados explícitamente.

    Puedes mostrarlos porque son valores fijos que no dependen de nada. Por ejemplo:

    MySQL 8.4
    SELECT home_type, 'literal' FROM Rooms
    GROUP BY home_type
    
    home_typeliteral
    Private roomliteral
    Entire home/aptliteral
    Shared roomliteral
  • resultados de funciones de agregación, es decir, valores calculados a partir de un conjunto de valores.

    Veremos las funciones de agregación en detalle en la siguiente lección. Pero, como ejemplo, echemos un vistazo a la función de agregación AVG. La función AVG recibe como argumento el nombre de la columna cuyo valor medio queremos calcular para cada grupo.

    MySQL 8.4
    SELECT home_type, AVG(price) as avg_price FROM Rooms
    GROUP BY home_type
    
    home_typeavg_price
    Private room89.4286
    Entire home/apt148.6667
    Shared room40

    Así, la consulta primero divide todos los registros de la tabla Rooms en 3 grupos según la columna home_type. Después, para cada grupo suma todos los valores de la columna price de las filas de ese grupo y divide el resultado entre el número de filas del grupo.

  • columnas de agrupación.

    Puedes mostrarlos porque, dentro de un mismo grupo, las columnas por las que se ha agrupado tienen el mismo valor.

Agrupación por 2 o más columnas

Ya hemos visto cómo se agrupan los registros de una tabla por una sola columna. Para ilustrarlo mejor, cuando la columna de agrupación es home_type, se ve más o menos así:

Agrupación por una columna

Al agrupar por 2 o más columnas, el principio es el mismo, solo que ahora los grupos formados se dividen además en grupos más pequeños según la segunda columna de agrupación.

Ejemplo de agrupación por home_type y has_tv:

Agrupación por dos columnas

¿Lo comprobamos? Al usar la cláusula GROUP BY, en SELECT podemos mostrar: