Inicio‎ > ‎SQL‎ > ‎Lecciones SQL‎ > ‎

T06 Filtrado de agregación


Having

Una vez que se obtiene información calculada sobre grupos de filas mediante el group by, se pueden filtrar estos resultados y mostrar sólo aquellos que nos interesen mediante la cláusula having. Having es a group by lo mismo que where a select-from

Al igual que la cláusula where selecciona filas, la cláusula having selecciona grupos; si en la where la condición que se especifica afecta a las tuplas de toda la tabla, el group by efectúa cálculos en función de esa selección previa y da como resultado una tabla con la información calculada para cada grupo dentro de esa selección. Sobre esta última el having eliminaría aquellas tuplas que no cumplen la condición.

Where filtra los datos almacenados en la tabla y having la información calculada.

Podemos entender el proceso de una consulta con group by-having como la ejecución previa de la parte select-from-where y, a partir de este resultado intermedio, la obtención de la información calculada con group by y, finalmente, el filtrado con having

¿Cuántas asignaturas imparte cada profesor?

select p.dni, nombre, count(*) asignaturas
from profesores p, imparte i
where p.dni = i.dni
group by p.dni, nombre

dni nombre asignaturas
21111222 EVA GOMEZ 2
21333444 RAFAEL ROMERO 1




¿Cuántas asignaturas imparten los profesores con 2 o más asignaturas?

select p.dni, nombre, count(*) asignaturas
from profesores p, imparte i
where p.dni = i.dni
group by p.dni, nombre
having count(*) >= 2

dni nombre asignaturas
21111222 EVA GOMEZ 2



Having no permite utilizar la etiqueta de las columnas calculadas, en este caso "asignaturas", ni tampoco el orden de la columna que interpretaría como un número entero.


Sin tener en cuenta la asignatura FBD, ¿cuántas asignaturas imparten los profesores con 2 o más asignaturas?

select p.dni, nombre, count(*) asignaturas
from profesores p, imparte i
where p.dni = i.dni
and asignatura != 'FBD'
group by p.dni, nombre
having count(*) >= 2

Ninguna fila seleccionada


Paso a paso, en la consulta anterior:
where ha eliminado las tuplas de imparte de código de asignatura FBD.
group by calcula, para cada profesor, el número de asignaturas que imparte. Puesto que no contamos FBD, Eva Gómez solo imparte, igual que Rafael Romero, una única asignatura.
having elimina del resultado del paso anterior todas aquellas tuplas con un valor en la cuenta de filas menor que 2. El resultado es vacío puesto que ninguno de los grupos supera la condición.

La condición del having no es necesariamente sobre el cálculo a mostrar, como se puede ver en el siguiente ejemplo.


¿Cuántas asignaturas imparte cada profesor en el caso de que la suma de créditos sea mayor que 5?

select p.dni, nombre, count(*) asignaturas
from profesores p, imparte i, asignaturas a
where p.dni = i.dni and a.codigo = i.asignatura
group by p.dni, nombre
having sum(creditos) > 5

dni nombre asignaturas
21111222 EVA GOMEZ 2
21333444 RAFAEL ROMERO 1




MySQL permite alejarse del SQL estándar

Hay que tener cuidado con una característica de MySQL que depende también de cómo esté configurado el servidor. El caso es que podría darse el caso de que MySQL acepte la siguiente orden en la que hemos omitido la columna nombre del group by:

DNI y nombre del coordinador y cuántas asignaturas coordina.

select dni, nombre, count(*) coordina
from asignaturas a, coordinadores c
where c.asig = a.codigo
group by dni;


En este caso, no hay problema puesto que para cada dni hay un único nombredni es el identificador de los coordinadores, pero no siempre es así. Como en muchas otras cosas, MySQL ofrece funcionalidades propias que el usuario puede elegir o no, pero alejarse del estándar dificulta la posibilidad de migrar a otros sistemas de gestión de base de datos.

MySQL deja en manos del que realiza la consulta el que tenga cuidado con el criterio de agrupación que utiliza asegurándose de que las columnas omitidas no van a alterar el resultado. Se puede ampliar esta información en el manual de MySQL. Hay autores que defienden este "alejamiento" del estándar, como Roland Bouman.

Otra característica que MySQL permite por defecto es utilizar having sin group by:

select * from asignaturas
having creditos > 3;

La idea que subyace en esta "permisividad" es que where no permite utilizar funciones de agregado mientras que having sí. Nuevamente, esta extensión de MySQL no es aceptada por todos los gestores de BD.

En cualquier caso, no recomendamos estas prácticas, al menos en un contexto de aprendizaje básico, ni tampoco las aceptaremos en la evaluación de este tipo de ejercicios.