Sie sind auf Seite 1von 12

Subconsultas

Definicin de subconsultas. Una subconsulta es una sentencia SELECT que aparece dentro de otra sentencia SELECT. Normalmente se utilizan para filtrar una clausula WHERE o HAVING con el conjunto de resultados de la subconsulta, aunque tambin pueden utilizarse en la lista de seleccin. Por ejemplo podriamos consultar el alquirer ltimo de un cliente.

SELECT CO_CLIENTE, NOMBRE, MARCA, MODDELO FROM ALQUILERES WHERE CO_CLIENTE = 1 AND FECHA_ALQUILER = (SELECT MAX(FECHA_ALQUILER) FROM ALQUILERES WHERE CO_CLIENTE = 1)

En este caso, la subconsulta se ejecuta en primer lugar, obteniendo el valor de la mxima fecha de alquier, y posteriormente se obtienen los datos de la consulta principal. Una subconsulta tiene la misma sintaxis que una sentencia SELECT normal exceptuando que aparece encerrada entre parntesis. La subconsulta se puede encontrar en la lista de seleccin, en la clusula WHERE o en la clusula HAVING de la consulta principal. Tiene las siguientes reestricciones:

No puede contener la clusula ORDER BY No puede ser la UNION de varias sentencias SELECT Si la subconsulta aparece en la lista de seleccin,o esta asociada a un operador igual "=" solo puede devolver un nico registro.

Referencias externas A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al

valor de una columna de la fila actual en la consulta principal, ese nombre de columna se denomina referencia externa. Una referencia externa es un campo que aparece en la subconsulta pero se refiere a la una de las tablas designadas en la consulta principal. Cuando se ejecuta una consulta que contiene una subconsulta con referencias externas, la subconsulta se ejecuta por cada fila de la consulta principal. En este ejemplo la subconsulta aparece en la lista de seleccin, ejecutandose una vez por cada fila que devuelve la consulta principal.

SELECT CO_EMPLEADO, NOMBRE, (SELECT MIN(FECHA_NOMINA) FROM NOMINAS WHERE CO_EMPLEADO = EMPLEADOS.CO_EMPLEADO) PRIMERA_NOMINA FROM EMPLEADOS;

Anidar subconsultas Las subconsultas pueden anidarse de forma que una subconsulta aparezca en la clusula WHERE (por ejemplo) de otra subconsulta que a su vez forma parte de otra consulta principal.

SELECT

CO_EMPLEADO, EMPLEADOS

FROM EMPLEADOS WHERE CO_EMPLEADO IN (SELECT CO_EMPLEADO FROM NOMINAS


WHERE

ESTADO

IN ( SELECT ESTADO FROM ESTADOS_NOMINAS WHERE EMITIDO = 'S' AND PAGADO = 'N')

Los resultados que se obtienen con subconsultas normalmente pueden conseguirse a travs de consultas combinadas ( JOIN ).

SELECT

CO_EMPLEADO,

NOMBRE FROM EMPLEADOS WHERE ESTADO IN (SELECT ESTADO FROM ESTADOS WHERE ACTIVO = 'S')

Podr escribirse como :

SELECT

CO_EMPLEADO, NOMBRE

FROM EMPLEADOS, ESTADOS WHERE EMPLEADOS.ESTADO = ESTADOS.ESTADO AND ESTADOS.ACTIVO = 'S'

Normalmente es ms rpido utilizar un JOIN en lugar de una subconsulta, aunque esto depende sobre todo del diseo de la base de datos y del volumen de datos que tenga. Utilizacion de subconsultas con UPDATE Podemos utilizar subconsultas tambin en consultas de actualizacin conjuntamente con UPDATE. Normalmente se utilizan para "copiar" el valor de otra tabla.

UPDATE

EMPLEADOS FROM NOMINAS WHERE NOMINAS.CO_EMPLEADO = EMPLEADOS.CO_EMPLEADO)

SET SALARIO_BRUTO = (SELECT SUM(SALIRO_BRUTO)

WHERE SALARIO_BRUTO IS NULL

La funcin EXISTS EXISTS es una funcin SQL que devuelve veradero cuando una subconsulta retorna al menos una fila.

SELECT

CO_CLIENTE, NOMBRE

FROM CLIENTES WHERE EXISTS (SELECT * FROM MOROSOS WHERE CO_CLIENTE = CLIENTES.CO_CLIENTE AND PAGADO = 'N')

La funcin EXISTS puede ser utilizada en cualquier sentencia SQL vida, SELECT, UPDATE, INSERT o DELETE.

Defenimos lo que significa subconsulta y mostramos las diferentes subconsultas que se pueden hacer.

Una subconsulta es una instruccin SELECT anidada dentro de una instruccin SELECT, SELECT...INTO, INSERT...INTO, DELETE, o UPDATE o dentro de otra subconsulta. Puede utilizar tres formas de sintaxis para crear una subconsulta:

comparacin [ANY | ALL | SOME] (instruccin sql) sql) [NOT] EXISTS (instruccin sql)

expresin [NOT] IN (instruccin

En donde:

comparacin expresin instruccin SQL

Es una expresin y un operador de comparacin que compara la expresin con el resultado de la subconsulta. Es una expresin por la que se busca el conjunto resultante de la subconsulta. Es una instruccin SELECT, que sigue el mismo formato y reglas que cualquier otra instruccin SELECT. Debe ir entre parntesis.

Se puede utilizar una subconsulta en lugar de una expresin en la lista de campos de una instruccin SELECT o en una clusula WHERE o HAVING. En una subconsulta, se utiliza una instruccin SELECT para proporcionar un conjunto de uno o ms valores especificados para evaluar en la expresin de la clusula WHERE o HAVING.

Se puede utilizar el predicado ANY o SOME, los cuales son sinnimos, para recuperar registros de la consulta principal, que satisfagan la comparacin con cualquier otro registro recuperado en la subconsulta. El ejemplo siguiente devuelve todos los productos cuyo precio unitario es mayor que el de cualquier producto vendido con un descuento igual o mayor al 25 por ciento:

SELECT * FROM Productos WHERE PrecioUnidad ANY ( SELECT PrecioUnidad FROM DetallePedido

WHERE Descuento = 0 .25 )

El predicado ALL se utiliza para recuperar nicamente aquellos registros de la consulta principal que satisfacen la comparacin con todos los registros recuperados en la subconsulta. Si se cambia ANY por ALL en el ejemplo anterior, la consulta devolver nicamente aquellos productos cuyo precio unitario sea mayor que el de todos los productos vendidos con un descuento igual o mayor al 25 por ciento. Esto es mucho ms restrictivo.

El predicado IN se emplea para recuperar nicamente aquellos registros de la consulta principal para los que algunos registros de la subconsulta contienen un valor igual. El ejemplo siguiente devuelve todos los productos vendidos con un descuento igual o mayor al 25 por ciento:

SELECT * FROM Productos WHERE IDProducto IN ( SELECT IDProducto FROM DetallePedido WHERE Descuento = 0.25 )

Inversamente se puede utilizar NOT IN para recuperar nicamente aquellos registros de la consulta principal para los que no hay ningn registro de la subconsulta que contenga un valor igual.

El predicado EXISTS (con la palabra reservada NOT opcional) se utiliza en comparaciones de verdad/falso para determinar si la subconsulta devuelve algn registro. Supongamos que deseamos recuperar todos aquellos clientes que hayan realizado al menos un pedido:

SELECT Clientes.Compaa, Clientes.Telfono FROM Clientes WHERE EXISTS ( SELECT FROM Pedidos WHERE Pedidos.IdPedido = Clientes.IdCliente )

Esta consulta es equivalente a esta otra:

SELECT Clientes.Compaa, Clientes.Telfono FROM Clientes WHERE IdClientes IN ( SELECT Pedidos.IdCliente FROM Pedidos )

Se puede utilizar tambin alias del nombre de la tabla en una subconsulta para referirse a tablas listadas en la clusula FROM fuera de la subconsulta. El ejemplo siguiente devuelve los nombres de los empleados cuyo salario es igual o mayor que el salario medio de todos los empleados con el mismo ttulo. A la tabla Empleados se le ha dado el alias T1:

SELECT Apellido, Nombre, Titulo, Salario FROM Empleados AS T1 WHERE

Salario = ( SELECT Avg(Salario) FROM Empleados WHERE T1.Titulo = Empleados.Titulo ) ORDER BY Titulo

En el ejemplo anterior, la palabra reservada AS es opcional.

SELECT Apellidos, Nombre, Cargo, Salario FROM Empleados WHERE Cargo LIKE 'Agente Ven*' AND Salario ALL ( SELECT Salario FROM Empleados WHERE Cargo LIKE '*Jefe*' OR Cargo LIKE '*Director*' )

(Obtiene una lista con el nombre, cargo y salario de todos los agentes de ventas cuyo salario es mayor que el de todos los jefes y directores.)

SELECT DISTINCT NombreProducto, Precio_Unidad FROM

Productos WHERE PrecioUnidad = ( SELECT PrecioUnidad FROM Productos WHERE NombreProducto = 'Almbar anisado' )

(Obtiene una lista con el nombre y el precio unitario de todos los productos con el mismo precio que el almbar anisado.)

SELECT DISTINCT NombreContacto, NombreCompania, CargoContacto, Telefono FROM Clientes WHERE IdCliente IN ( SELECT DISTINCT IdCliente FROM Pedidos WHERE FechaPedido <#07/01/1993# )

(Obtiene una lista de las compaas y los contactos de todos los clientes que han realizado un pedido en el segundo trimestre de 1993.)

SELECT Nombre, Apellidos FROM Empleados AS E WHERE EXISTS ( SELECT * FROM Pedidos AS O

WHERE O.IdEmpleado = E.IdEmpleado )

(Selecciona el nombre de todos los empleados que han reservado al menos un pedido.)

SELECT DISTINCT Pedidos.Id_Producto, Pedidos.Cantidad, ( SELECT Productos.Nombre FROM Productos WHERE Productos.IdProducto = Pedidos.IdProducto ) AS ElProducto FROM Pedidos WHERE Pedidos.Cantidad = 150 ORDER BY Pedidos.Id_Producto

(Recupera el Cdigo del Producto y la Cantidad pedida de la tabla pedidos, extrayendo el nombre del producto de la tabla de productos.)

SELECT NumVuelo, Plazas FROM Vuelos WHERE Origen = 'Madrid' AND Exists ( SELECT T1.NumVuelo FROM Vuelos AS T1 WHERE T1.PlazasLibres > 0 AND T1.NumVuelo=Vuelos.NumVuelo)

(Recupera nmeros de vuelo y capacidades de aquellos vuelos con destino Madrid y plazas libres

Supongamos ahora que tenemos una tabla con los identificadores de todos nuestros productos y el stock de cada uno de ellos. En otra tabla se encuentran todos los pedidos que tenemos pendientes de servir. Se trata de averiguar que productos no se podemos servir por falta de stock.

SELECT PedidosPendientes.Nombre FROM PedidosPendientes GROUP BY PedidosPendientes.Nombre HAVING SUM(PedidosPendientes.Cantidad < ( SELECT Productos.Stock FROM Productos WHERE Productos.IdProducto = PedidosPendientes.IdProducto ) )

Supongamos que en nuestra tabla de empleados deseamos buscar todas las mujeres cuya edad sea mayor a la de cualquier hombre:

SELECT Empleados.Nombre FROM Empleados WHERE Sexo = 'M' AND Edad > ANY (SELECT Empleados.Edad FROM Empleados WHERE Sexo ='H')

lo que sera lo mismo:

SELECT Empleados.Nombre

FROM Empleados WHERE Sexo = 'M' AND Edad > (SELECT Max( Empleados.Edad )FROM Empleados WHERE Sexo ='H')

La siguiente tabla muestra algn ejemplo del operador ANY y ALL

Valor 1 Operador Valor 2 Resultado 3 3 3 3 3 > ANY = ANY = ANY > ALL < ALL (2,5,7) (2,5,7) (2,3,5,7) (2,5,7) (5,6,7) Cierto Falso Cierto Falso Falso

El operacion =ANY es equivalente al operador IN, ambos devuelven el mismo resultado.

Das könnte Ihnen auch gefallen