Inicio‎ > ‎SQL‎ > ‎Lliçons SQL‎ > ‎

T06 Filtrat de agregació


Having

Una vegada que s’obté informació calculada sobre grups de files mitjançant el group by, es poden filtrar aquests resultats i mostrar només aquells que ens interessen mitjançant la clàusula having. Having és a group by el mateix que where a select-from

Al igual que la clàusula where selecciona files, la clàusula having selecciona grups; si en la where la condició que s’especifica afecta a les tuplas de tota la taula, el group by efectua càlculs en funció d'aquesta selecció prèvia i dóna com resultat una taula amb la informació calculada per a cada grup dins d’aquesta selecció. Sobre aquesta última el having eliminaria aquelles tuplas que no compleixen la condició.

Where filtra les dades emmagatzemades en la taula i having la informació calculada.

Podem entendre el procés d’una consulta amb group by-having com  l’execució prèvia de la part select-from-where i, partir d’aquest resultat intermedi, l’obtenció de la informació calculada amb group by i, finalment, el filtrat amb having

Quantes assignatures imparteix cada professor? 

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

dninombreasignaturas
21111222EVA GOMEZ2
21333444RAFAEL ROMERO1




Quantes assignatures imparteixen els professors amb 2 o més assignatures?

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

dninombreasignaturas
21111222EVA GOMEZ2



Having no permet utilitzar l’etiqueta de les columnes calculades, en aquest cas "asignaturas", ni tampoc l’orde de la columna que interpretaria com un número sencer. 


Sense tenir en compte l’assignatura FBD, quantes assignatures imparteixen els professors amb 2 o més assignatures? 

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

Cap fila seleccionada


Pas a pas, en la consulta anterior:
  1. where ha eliminat les tuplas d’imparteix de codi d’assignatura FBD.
  2. group by calcula, per a cada professor, el nombre d'assignatures que imparteix. Ja que no comptem FBD, Eva Gómez només imparteix, igual que Rafael Romero, una única assignatura.
  3. having elimina del resultat del pas anterior totes aquelles tuplas amb un valor en el compte de files menor que 2. El resultat és buit ja que cap dels grups supera la condició.

La condició del having no és necessàriament sobre el càlcul a mostrar, com es pot veure en el següent exemple.

Quantes assignatures imparteix cada professor en el cas que la suma de creditos siga major 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

dninombreasignaturas
21111222EVA GOMEZ2
21333444RAFAEL ROMERO1




MySQL permet allunyar-se del SQL estàndard

Cal tenir atenció amb una característica de MySQL que depèn també de com estiga configurat el servidor. El cas és que podria donar-se el cas que MySQL accepte la següent orde en què hem omès la columna nombre del group by:

DNI i nom del coordinador i quantes assignatures coordina.

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

En aquest cas, no hi ha problema ja que per a cada dni hi ha un únic nombredni és l’identificador dels coordinadors, però no sempre és així. Com en moltes altres coses, MySQL ofereix funcionalitats pròpies que l’usuari pot triar o no, però allunyar-se de l’estàndard dificulta la possibilitat de migrar a altres sistemes de gestió de base de dades. 

MySQL deixa en mans de què realitza la consulta el que tinga atenció amb el criteri d’agrupació que utilitza assegurant-se de que les columnes omeses no alteraran el resultat. Es pot ampliar aquesta informació en el manual de MySQLHi ha autors que defenen aquest "allunyament" de l’estàndard, com Roland Bouman.

Una altra caracteristica que MySQL permet per defecte és utilitzar having sense group by:

select * from asignaturas
having creditos > 3;

La idea que subjau en aquesta "permisivitat" és que where no permet utilitzar funcions d’agregat mentres que having sí. Novament, aquesta extensió de MySQL no és acceptada per tots els gestors de BD.

En tot cas, 
Comments