Académique Documents
Professionnel Documents
Culture Documents
Definiciones
Una subconsulta tiene la misma sintaxis que una sentencia SELECT normal exceptuando
que aparece encerrada entre parntesis, no puede contener la clusula ORDER BY, ni
puede ser la UNION de varias sentencias SELECT, adems tiene algunas restricciones en
cuanto a nmero de columnas segn el lugar donde aparece en la consulta principal. Estas
restricciones las iremos describiendo en cada caso.
Las consultas que utilizan subconsultas suelen ser ms fciles de interpretar por el
usuario.
Referencias externas
A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al valor
de una columna en la fila actual de la consulta principal, ese nombre de columna se
denomina referencia externa.
Una referencia externa es un nombre de columna que estando en la subconsulta, no se
refiere a ninguna columna de las tablas designadas en la FROM de la subconsulta sino a
una columna de las tablas designadas en la FROM de la consulta principal. Como la
subconsulta se ejecuta por cada fila de la consulta principal, el valor de la referencia externa
ir cambiando.
Ejemplo:
Anidar subconsultas
Ejemplo:
En este ejemplo, por cada linea de pedido se calcula la subconsulta de clientes, y esto
se repite por cada empleado, en el caso de tener 10 filas de empleados y 200 filas de
pedidos (tablas realmente pequeas), la subconsulta ms interna se ejecutara 2000 veces
(10 x 200).
En la clusula FROM
Se suele utilizar subconsultas en las clusulas WHERE o HAVING cuando los datos que
queremos visualizar estn en una tabla pero para seleccionar las filas de esa tabla
necesitamos un dato que est en otra tabla.
Ejemplo:
En este ejemplo listamos el nmero y nombre de los empleados cuya fecha de contrato
sea igual a la primera fecha de todos los pedidos de la empresa.
En todos los tests estudiados a continuacin expresion puede ser cualquier nombre de
columna de la consulta principal o una expresin vlida como ya vimos en el tema 2.
La sintaxis es la siguiente:
SELECT oficina, ciudad Lista las oficinas cuyo objetivo sea superior a la
FROM oficinas suma de las ventas de sus empleados.
WHERE objetivo > (SELECT En este caso la subconsulta devuelve una nica
SUM(ventas) FROM empleados columna y una nica fila (es un consulta de
WHERE empleados.oficina = resumen sin GROUP BY)
oficinas.oficina)
Este test es una extensin del test de comparacin y del test de conjunto. Compara el
valor de la expresin con cada uno de los valores producidos por la subconsulta. La
subconsulta debe devolver una nica columna sino se produce un error.
Tenemos el test ANY (algn, alguno en ingls) y el test ALL (todos en ingls).
La sintaxis es la siguiente:
El test ANY.
El test ALL.
SELECT oficina, ciudad En este caso se listan las oficinas cuyo objetivo
FROM oficinas sea superior a todas las sumas.
WHERE objetivo > ALL (SELECT
SUM(cuota) FROM empleados
GROUP BY oficina)
La sintaxis es la siguiente:
NOTA. Cuando se trabaja con tablas muy voluminosas el test EXISTS suele dar mejor
rendimiento que el test IN.
Dentro de una consulta se puede utilizar una columna del origen de la consulta
principal, una referencia externa.
el test ANY
el test ALL
el test IN
el test EXISTS
1 Listar los nombres de los clientes que tienen asignado el representante Alvaro Jaumes
(suponiendo que no pueden haber representantes con el mismo nombre).
3 Listar los vendedores que no trabajan en oficinas dirigidas por el empleado 108.
4 Listar los productos (idfab, idproducto y descripcin) para los cuales no se ha recibido
ningn pedido de 25000 o ms.
5 Listar los clientes asignados a Ana Bustamante que no han remitido un pedido superior
a 3000 pts.
6 Listar las oficinas en donde haya un vendedor cuyas ventas representen ms del 55%
del objetivo de su oficina.
7 Listar las oficinas en donde todos los vendedores tienen ventas que superan al 50%
del objetivo de la oficina.
8 Listar las oficinas que tengan un objetivo mayor que la suma de las cuotas de sus
vendedores.
Ejercicio 1
Ejercicio 2
Ejercicio 3
SELECT numemp, nombre, oficina Con esta solucin tenemos el mismo problema
FROM empleados que con NOT IN , cuando la oficina del
WHERE oficina <> ALL ( SELECT empleado es nula todos los resultados de las
oficina FROM oficinas WHERE dir = comparaciones individuales son nulos por los
108); que el test ALL da nulo y no se seleccionan los
empleados con oficina nula.
Ejercicio 4
Ejercicio 5
Ejercicio 6
Ejercicio 7
Solucin 1
SELECT *
FROM oficinas
WHERE ((objetivo * 0.5) <= ALL (
SELECT ventas FROM empleados
WHERE empleados.oficina =
oficinas.oficina AND ventas IS NOT
NULL) )
AND ( EXISTS ( SELECT * FROM
empleados WHERE
empleados.oficina =
oficinas.oficina ) );
Ejercicio 8
SELECT *
FROM oficinas
WHERE objetivo > ( SELECT
SUM(cuota) FROM empleados
WHERE empleados.oficina =
oficinas.oficina);
6.1. Introduccin
Una subconsulta es una consulta que aparece dentro de otra consulta o subconsultas,
en la lista de seleccin o en la clusula WHERE o HAVING, originalmente no se podan
incluir en la lista de seleccin.
Una subconsulta se denomina tambin consulta o seleccin interna, mientras que la
instruccin que contiene la subconsulta es conocida como consulta o seleccin externa.
Aparece siempre encerrada entre parntesis y tiene la misma sintaxis que una sentencia
SELECT normal con alguna limitacin:
No puede incluir una clusula COMPUTE o FOR BROWSE y slo puede incluir una clusula
ORDER BY cuando se especifica tambin una clusula TOP.
Ejemplo de subconsulta: Listar los empleados cuya cuota no supere el importe vendido
por el empleado.
SELECT nombre
FROM empleados
FROM pedidos
Por cada fila de la tabla de empleados (de la consulta externa) se calcula la subconsulta
y se evala la condicin, por lo que utilizar una subconsulta puede en algunos casos
ralentizar la consulta, en contrapartida se necesita menos memoria que una composicin
de tablas.
Muchas de las instrucciones Transact-SQL que incluyen subconsultas se pueden formular
tambin utilizando composiciones de tablas. Otras preguntas se pueden formular slo con
subconsultas.
En Transact-SQL, normalmente no hay una regla fija en cuanto a diferencias de rendimiento
entre una instruccin que incluya una subconsulta y una versin semnticamente
equivalente que no la incluya.
Podremos utilizar una subconsulta siempre y cuando no se quiera que aparezcan en el
resultado columnas de la subconsulta ya que si una tabla aparece en la subconsulta y no
en la consulta externa, las columnas de esa tabla no se pueden incluir en la salida (la lista
de seleccin de la consulta externa).
FROM oficinas
FROM empleados
La columna oficina se encuentra en los dos orgenes (oficinas y empleados) pero esta
consulta no dar error (no se nos pedir cualificar los nombres como pasara en una
composicin de tablas), dentro de la subconsulta se considera oficina el campo de la
tabla empleados. Con lo que comparara la oficina del empleado con la misma oficina del
empleado y eso no es lo que queremos, queremos comparar la oficina del empleado con la
oficina de oficinas, lo escribiremos pues as para forzar a que busque la columna en la
tabla oficinas.
FROM oficinas
FROM empleados
Los operadores de comparacin sin modificar son los operadores de comparacin que
vimos con la clusula WHERE.
Sintaxis:
SELECT nombre
FROM empleados
FROM pedidos
La subconsulta devuelve una sola columna y como mucho una fila ya que es una consulta
de resumen sin clusula GROUP BY.
Ejemplo:
SELECT *
FROM empleados
FROM oficinas
Por cada empleado se calcula la lista de las oficinas del Este (n de oficina) y se evala
si la oficina del empleado est en esta lista. Obtenemos pues los empleados de oficinas del
Este.
SELECT *
FROM empleados
FROM oficinas
La lista generada est vaca por lo que la condicin IN devuelve FALSE y en este caso
no sale ningn empleado.
Muchas veces la misma pregunta se puede resolver mediante una composicin de tablas.
SELECT empleados.*
SELECT *
FROM empleados
FROM oficinas
Devuelve los empleados cuya oficina no est en la lista generada por la subconsulta, es
decir empleados que trabajan en oficinas que no son del Este.
* En la consulta anterior no salen los empleados que no tienen oficina ya que para esos
empleados la columna oficina contiene NULL por lo que no se cumple el NOT IN.
* Si la subconsulta no devuelve ninguna fila, la condicin se cumplir para todas las filas
de la consulta externa, en este caso todos los empleados.
* Si la subconsulta devuelve algn valor NULL, la condicin NOT IN es NULL lo que nos
puede ocasionar algn problema.
Por ejemplo, queremos obtener las oficinas que no estn asignadas a ningn empleado.
SELECT *
FROM Oficinas
FROM empleados);
Esta consulta no devuelve ninguna fila cuando s debera ya que hay oficinas que nos
estn asignadas a ningn empleado. El problema est en que la columna oficina de la tabla
empleados admite nulos por lo que la subconsulta devuelve valores nulos en todos los
empleados que no estn asignados a ninguna oficina. Estos valores nulos hacen que no se
cumpla el NOT IN. La solucin pasa por eliminar estos valores molestos:
SELECT *
FROM Oficinas
FROM empleados
FROM empleados
FROM pedidos
En este caso, como un empleado puede tener varios pedidos hay que aadir DISTINCT
para eliminar las repeticiones de empleados (si un empleado tiene varios pedidos de ACI
aparecera varias veces).
Sin embargo esta sentencia con NOT IN, queremos los empleados que no tienen pedidos
de ACI:
FROM empleados
FROM pedidos
Esta consulta devuelve los empleados que tienen pedidos que no son de ACI, pero un
empleado puede tener pedidos de ACI y otros de otros fabricantes y por estos otros saldra
en el resultado cuando s tiene pedidos de ACI y no debera salir.
Hay que tener mucho cuidado con este tipo de preguntas.
Objetivo
Realizar consultas que incluyan una subconsulta en la clusula WHERE, introducida por
el operador IN.
SELECT numclie,nombre
FROM clientes
AND producto LIKE '4100%' AND fechapedido >= '01/01/90' AND fechapedido
<'16/04/90');
Resultado:
numclie nombre
2102 Alvaro Rodrguez
2118 Junpero Alvarez
Listar los empleados (numemp, nombre) que han realizado un pedido que represente
ms del 1% de su cuota.
Resultado:
numemp nombre
105 Vicente Pantalla
107 Jorge Gutirrez
109 Mara Sunta