sábado, 11 de marzo de 2017

Subconsultas en SQL

Son aquellas sentencias SELECT que se encuentran anidadas en una cláusula WHERE o HAVING de otra sentencia de orden superior. Cada una de las subconsultas debe incluir al menos una cláusula SELECT y otra FROM y se escriben entre paréntesis para que el gestor de la base de datos la realice en primer lugar.

Las subconsultas pueden ser correlacionadas o no correlacionadas. Una consulta es correlacionada si su resultado depende de la SELECT externa de la que depende. Cualquier otra subconsulta es denominada no correlacionada.

Subconsultas en SQL



Las subconsultas o consultas subordinadas permiten:

1- Comparar un valor con el resultado de una sentencia SELECT, por ejemplo, en una cláusula WHERE.

SELECT descripcion
FROM almacen
WHERE precio > (SELECT MAX(precio)
             FROM pedidos)

En este caso, el gestor de la base de datos primero busca el mayor precio de un producto de la tabla pedidos, y luego devuelve todos los productos de la tabla almacén que tengan un precio superior al mayor precio de la tabla pedidos anteriormente buscado.

2- Determinar si una expresión se halla incluida en los resultados de una sentencia SELECT.

SELECT descripcion, precio
FROM pedidos
WHERE descripcion IN (SELECT DISTINCT descripcion)
                FROM deudores)

En este caso, primero se buscan todos los productos diferentes que aparecen en la tabla deudores (p.ej. son deficitarios) y después se obtiene el precio y la descripción de los pedidos que actualmente son deficitarios.

Nota: Supongamos que, en vez de pedirnos los productos deficitarios nos hubieran pedido los productos no deficitarios. En este caso bastaría con sustituir  IN por NOT IN, pero esto puede haber casos especiales que no devuelvan ninguna fila aunque nosotros sabemos que debe haber varios, en este caso la solución consiste en anidar dos subconsultas, una con NOT IN y la otra con IN de este modo.

SELECT descripcion, precio 
FROM pedidos 
WHERE descripcion NOT IN  (SELECT descripcion 
                           FROM pedidos 
                           WHERE descripcion IN               (SELECT distinct(descripcion)FROM deudores))


3- Determinar si se ha seleccionado alguna fila en la SELECT subordinada.

SELECT descripcion
FROM pedidos
WHERE EXISTS (SELECT * FROM grupos)

En este caso se pregunta si hay algo en la tabla grupos.

Las comparaciones que hemos visto, forman siempre parte de predicados en la cláusula WHERE, si bien también pueden utilizarse en HAVING. De este modo, las expresiones se utilizan en el marco de predicados.

Subconsultas que devuelven un único valor

En ocasiones una subconsulta devuelve un único valor que puede ser utilizado en una expresión directamente, como puede verse en el siguiente ejemplo:

SELECT descripcion
FROM pedidos
WHERE precio > (SELECT precio
               FROM pedidos
               WHERE descripcion = 'Portátil modelo A45')

Aquí se busca el precio del portátil modelo A45 y luego se muestran todos los productos con pedidos que sean más caros que este portátil.

Predicados cuantificados

Una sentencia  SELECT subordinada normalmente devolverá varios valores. Si deseamos comparar un valor con el resultado de una subconsulta, tenemos que  implementar algún tipo de mecanismo para obtener un único valor del resultado completo de la SELECT subordinada. Los predicados así construidos se llaman predicados cuantificados, el resultado de la SELECT subordinada debe ser una tabla con una sola columna pero con cero o más filas.

ALL

Este predicado cuantificado es verdadero si la comparación es verdadera para todos y cada uno de los valores resultantes en la sentencia subordinada. Si la sentencia subordinada devuelve una tabla vacía, el predicado también tomará el valor verdadero. El predicado será falso si la comparación es falsa para alguno de los valores devueltos y verdadera en caso contrario.

SELECT descripcion
FROM pedidos
WHERE precio > ALL(SELECT precio
                   FROM almacen
   ORDER BY descripción)

La subconsulta devuelve un conjunto de resultados de una columna. El tipo de datos de la columna devuelta debe ser el mismo tipo de datos que el tipo de datos de la expresión escalar. Es una instrucción SELECT restringida en la que no se permiten la cláusula ORDER BY ni la palabra clave INTO.



Esta consulta seleccionaría todas aquellas descripciones en tabla pedidos que tienen un mayor precio a todas las descripciones de la tabla almacen

ANY y SOME

Estos predicados cuantificados, equivalentes en su significado, son verdaderos si la comparación es verdadera para al menos uno de los valores resultantes en la sentencia subordinada. Si la sentencia subordinada devuelve una tabla vacía, el predicado toma el valor falso. Si devuelve uno o más valores nulos, el predicado será verdadero si la comparación es verdadera para alguno de los otros valores devueltos y desconocido si para todos ellos es falsa.

SELECT descripcion
FROM pedidos
WHERE precio > SOME  (SELECT precio
                          ORDER BY descripcion FROM almacen)

Selecciona todos los productos de la tabla pedidos que no son menores en  precio a todos los productos de la tabla almacen.

Predicado EXISTS

Es cierto cuando la sentencia subordinada encuentra como resultado al menos una fila. Es decir, este predicado es verdadero si el resultado de la sentencia subordinada no es una tabla vacía y falso en caso contrario. Pero no puede tomar un valor desconocido.

EXISTS (sentencia subordinada)

La sentencia subordinada puede dar lugar a una tabla con cualquier número de columnas.

Subconsultas correlacionadas

Llamamos sentencias subordinadas correlacionadas a aquellas en las que el resultado de la sentencia subordinada no puede evaluarse independiente de sus sentencias antecedentes. Por tanto, el gestor de la base de datos no puede evaluarse independientemente, pues su resultado puede depender de qué filas se estén operando.

SELECT descripcion, precio
FROM pedidos p
WHERE peso > (SELECT AVG(peso)
              FROM pedidos WHERE id_grupo = p.id_grupo)

En este caso se calcula el peso medio de cada grupo de productos y luego se muestran sólo aquellos productos con pedidos cuyo peso supera a la media de su grupo.




No hay comentarios:

Publicar un comentario