En otra lección de este blog (que debes leer aquí antes que ésta) se discute sobre la regla de SQL que obliga a que, en una consulta de agrupación, si se quiere recuperar en el select algún dato (o expresión que use algún dato) que no sea el resultado de una función de agregación, ese dato debe estar en el criterio de agrupación de la cláusula group by. Esa regla también se aplica a la cláusula having: ésta solo puede tener funciones de agregación o campos del criterio de agrupación.
La razón es la misma que para el select: si se va a imponer una condición en el grupo, que para eso sirve having, los datos que intervienen en esa condición o bien son resultado de funciones de agregación, o valores constantes, o valores de campos que tienen un valor uniforme en todas las tuplas reunidas en cada grupo.
Por ejemplo, supongamos que disponemos de la tabla Empleado, con datos sobre los salarios de los empleados y sobre quienes son sus jefes:
+-----------+-----------+------------------+---------+-----------+ | NSS | nombre | apellidos | salario | jefe | +-----------+-----------+------------------+---------+-----------+ | 121232321 | Diana | Dalmau Duport | 1900 | 888665555 | | 123456789 | Juan | Suárez García | 1800 | 333445555 | | 222333000 | Leyre | Iturrioz Mañas | 2000 | 888665555 | | 333445555 | Francisco | Gómez Fiz | 2400 | 888665555 | | 453453453 | Josefa | Cea Silva | 1500 | 333445555 | | 555555555 | Julián | Márquez Pérez | 2400 | 222999444 | | 666884444 | Ramón | Piedra Trujillo | 2280 | 333445555 | | 888665555 | Pilar | Requena Santos | 3300 | NULL | | 987654321 | Ana | Álvarez González | 2580 | 888665555 | | 987987987 | Juan | Suárez Roca | 1500 | 987654321 | | 999887777 | Alicia | Vives Carrascosa | 1500 | 987654321 | +-----------+-----------+------------------+---------+-----------+
Imaginemos que nos piden los nombres de los jefes que cobran un 50% más que el salario medio de sus subordinados. Lo siguiente sería erróneo:
select j.Nombre, j.Apellidos
from empleado j join empleado s on s.Jefe=j.NSS
group by j.Nombre, j.Apellidos
having j.Salario > avg(s.Salario)*1.5;
No podemos usar el campo j.Salario en la condición del having porque no está incluido en el criterio de agrupación, y por tanto, no tenemos garantía de que sea uniforme en todas las filas de cada grupo. En este caso, incluso MySQL muestra un error de ejecución.
Lo siguiente sí sería correcto (notar la inclusión de j.Salario en el criterio de agrupación)
select j.Nombre, j.Apellidos
from Empleado j join Empleado s on s.Jefe=j.NSS
group by j.Nombre, j.Apellidos, j.Salario
having j.Salario > avg(s.Salario)*1.5;
No hay comentarios:
Publicar un comentario