1. Bases de dades relacionals

1.11. Consultes avançades: subconsultes

En ocasions desitgem realitzar un tipus de pregunta sobre les nostres dades, però no és factible perquè l’organització en taules escollida no ho permet. Per resoldre aquest problema, MySQL permet enniuar una consulta dins d’una altra, amb l’objectiu d’utilitzar la pregunta interior per donar-li la forma apropiada a les dades, que podran ser tractades posteriorment mitjançant la consulta exterior.

Sintaxi bàsica d’una subconsulta:

SELECT llista_columnes
FROM nombre_taula
WHERE condició = (SELECT llista_columnes2
FROM nombre_taula2
WHERE condicions);

Sintàcticament, des del punt de vista de la consulta principal, la subconsulta interior exercirà el paper d’una taula convencional. Per aquesta raó, és possible assignar un nom tant a la consulta interior com als atributs dels resultats que se’n desprendran. Per a això emprarem la clàusula AS, que permet associar un nom a un grup d’operacions o atributs en SQL. El nom emprat per a aquests atributs resulta útil per referir-s’hi des de la consulta exterior.

SELECT subconsulta.valor1,..., subconsulta.valorn FROM
   (SELECT atribut1 AS valor1,..., atributn AS valorn
   FROM taula GROUP BY tributi) AS subconsulta;

Per exemplificar la classe d’escenari on les subconsultes resulten potencialment interessants, imaginem una taula genèrica anomenada taula amb dos atributs, que denominarem clase i subclsse. Cada registre d’aquesta taula pertany a una classe general, i dins d’aquesta classe, a una subclasse més específica. Suposem que ens agradaria calcular la mitjana de subclasses diferents, classe per classe, que han estat utilitzades per etiquetar cada registre. Per obtenir la resposta, definirem una subconsulta que rebrà el nom de contador. Aquesta subpregunta agruparà les dades per classes per comptar el nombre total de subclasses assignat als registres de cada classe principal. Finalment, la consulta exterior simplement haurà de calcular la mitjana dels totals calculats per la subconsulta.

classe1 subclassex
classe1 subclassey
classe1 subclassez
classe2 subclassea
classe2 subclasseb
classe3 subclassen
...
--------------------------------------------

SELECT AVG (comptador.totals) FROM

 (SELECT count(subclasse) AS totals

  FROM taula GROUP BY classe) AS comptador;