Inicio‎ > ‎SQL‎ > ‎Lecciones SQL‎ > ‎T02 Consultas‎ > ‎

T02B Consultas anidadas

Las subconsultas, dependiendo del valor esperado y del tipo de comparación deseado se pueden utilizar de 3 formas:

  • expr opcompara {ALL|[ANY|SOME]} (orden select)
  • expr [NOT] IN (orden select)
  • [NOT] EXISTS (orden select)

donde opcompara es cualquier operador de comparación. 

Los valores posibles a devolver por una orden select anidada son :

  • nada
  • un valor único (una fila y una columna),
  • un conjunto de valores (varias filas y una columna).

Siempre que la subconsulta devuelva algo, únicamente será en una y nada más que una columna (salvo el operador EXISTS, que se verá más adelante).


de valor escalar

expr opcompara (orden select) 

Podemos utilizar los operadores de comparación para preguntar si el valor de una determinada expresión es mayor, menor, igual, etc. que el resultado de la subconsulta, siempre y cuando ésta devuelva una única fila y una única columna, es decir, un valor escalar.

select descripcion
from asignaturas
where creditos = (select creditos from asignaturas where creditos < 9)

SQL Error: Subquery returns more than 1 row


Aunque también se puede utilizar cualquier consulta de la que estamos seguros que nos va a devolver una fila y una columna, lo más habitual es que sea el resultado de buscar un valor concreto de una clave primaria (en general, de cualquier combinación de columnas que no admita duplicados)


Asignaturas que tienen más créditos que la asignatura HI.

select * from asignaturas
where creditos >(select creditos
from asignaturas
where codigo = 'HI')

codigodescripcioncreditoscreditosp
DGBDDISEÑO Y GESTION DE BASES DE DATOS6.03.0
FBDFUNDAMENTOS DE LAS BASES DE DATOS6.01.5
FPFUNDAMENTOS DE LA PROGRAMACION9.04.5
PCPROGRAMACION CONCURRENTE6.01.5


de lista de valores

expr opcompara ALL|[ANY|SOME] (orden select) 

Cuando la tabla resultado contiene más de una fila (pero una única columna, insistimos) hay que utilizar un modificador para el operador de comparación.


Asignaturas que tienen más créditos que las demás (asignaturas que tienen la máxima cantidad de créditos en la base de datos)

select descripcion
from asignaturas
where creditos >= ALL (select creditos from asignaturas)

descripcion
FUNDAMENTOS DE LA PROGRAMACION
 

El número en créditos de la asignatura tiene que ser mayor o igual que todos (all) los valores obtenidos en la subconsulta (que es la relación de créditos de todas las asignaturas). También se podría haber formulado como

select descripcion
from asignaturas
where creditos (select max(creditos) from asignaturas)



Nombre de las asignaturas que no son las que menos créditos tienen.

select descripcion
from asignaturas
where creditos > ANY (select creditos from asignaturas)

descripcion
DISEÑO Y GESTION DE BASES DE DATOS
FUNDAMENTOS DE LAS BASES DE DATOS
FUNDAMENTOS DE LA PROGRAMACION
PROGRAMACION CONCURRENTE

Serían todas aquellas asignaturas cuyos créditos superen al menos a uno (any) de los valores devueltos por la subconsulta. Los modificadores some y any son sinónimos. Una solución alternativa es

select descripcion
from asignaturas
where creditos != (select min(creditos) from asignaturas)



Nombre de los profesores que imparten una asignatura que no sea la máxima en número de créditos

select nombre
from profesores p, asignaturas a, imparte i
where p.dni = i.dni and i.asignatura = a.codigo
and creditos < ANY ( select creditos from asignaturas )

nombre
EVA GOMEZ
EVA GOMEZ
RAFAEL ROMERO


NOTA:

En versiones anteriores de MySQL se producía un error que imposibilitaba la ejecución de estos ejemplos. Por un cambio de configuración que, a su vez, descubría un fallo de la versión instalada de MySQL, las expresiones expr opcompara {ALL|[ANY|SOME]} provocaban un error de compilación y no podían ejecutarse —en la versión actual ya no ocurre—. 

Lo cierto es que la mayor parte de estos ejemplos tienen que ver con "el máximo x, el mínimo x" por lo que son equivalentes:

select descripcion, creditos
from asignaturas
where creditos <= ALL( select creditos from asignaturas );


select descripcion, creditos
from asignaturas
where creditos = ( select min(creditos) from asignaturas );

Insistimos, en este tipo de consultas. En otras es posible que no se disponga de esta alternativa.


Finalmente, obsérvese que estas expresiones son equivalentes:
expr IN (orden select) ≈ expr=ANY(orden select)
expr NOT IN (orden select) ≈ expr<>ALL(orden select)

Comments