Está en la página 1de 21

Parcial II: 3 Leccin 18

1

Sub consultas avanzadas
Objetivo
Despus de completar este captulo conocer lo siguiente:
Escribir una consulta de mltiples columnas
Describir y explicar el comportamiento de las sub consultas cuando
valores nulos son recuperados
Escribir una sub consulta en la clusula FROM
Utilizar sub consultas escalares en SQL
Describir los tipos de problemas que pueden ser resueltos con sub
consultas correlacionadas
Escribir sub consultas correlacionadas
Actualizar y eliminar filas utilizando sub consultas correlacionadas
Usar los operadores EXISTS y NOT EXISTS
Usar la clusula WITH


Qu es una sub consulta?
Una sub consulta es una sentencia SELECT que es incrustada en una clusula
de otra sentencia SQL, llamada sentencia padre.
La sub consulta (consulta interna) obtiene un valor que es usado por la
sentencia padre. Usar una sub consulta anidada es equivalente a ejecutar dos
consultas secuenciales y utilizar el resultado de la consulta interna como valor
de bsqueda en la consulta externa (consulta principal).

Las sub consultas pueden ser usadas para los siguientes propsitos:
Proveer valores para condiciones en clusulas WHERE, HAVING y
START WITH de sentencias SELECT
Definir el conjunto de filas a ser insertadas en una tabla de una
sentencia INSERT o CREATE TABLE
Parcial II: 3 Leccin 18
2

Definir el conjunto de filas a ser incluidas en una vista o snapshot en una
sentencia CREATE VIEW o CREATE SNAPSHOT
Definir uno o ms valores para ser asignados a filas existentes en una
sentencia UPDATE
Definir una tabla para ser operada por el contenido de una consulta.
(Esto se hace colocando la sub consulta en la clusula FROM. Esto
puede hacerse tambin en sentencias INSERT, UPDATE y DELETE.

Nota: Una sub consulta es evaluada en una ocasin para toda la sentencia
padre.


Sub consultas
Se pueden construir sentencias poderosas utilizando sub consultas. Las sub
consultas pueden ser muy tiles cuando necesites seleccionar filas de una
tabla con una condicin que dependa de los datos de la misma u otra tabla. Las
sub consultas son muy tiles para escribir sentencias SQL que necesiten
valores de un o ms valores condicionales desconocidos.

Donde:

operator incluye un operador de comparacin como >, = o IN

Nota: los operadores de comparacin se encuentran en dos clases:
operadores de fila nica (>, =, >=, <, <>, <=) y operadores de mltiples filas
(IN, ANY, ALL)

Las sub consultas son a menudo referidas como sentencias SELECT anidadas,
sub-SELECT, o SELECT internos.
Las consultas internas y externas pueden recuperar datos de la misma tablao
de tablas diferentes.

Parcial II: 3 Leccin 18
3


Usando una sub consulta
En el ejemplo anterior, la consulta interna obtiene el salario del empleado con
nmero 149. La consulta externa utiliza el resultado de la consulta interna para
desplegar los nombres de todos los empleados ganen mas que el empleado
149.

Ejemplo

Despliegue los nombres de todos los empleados que ganen menos que el
salario promedio de la compaa.



Parcial II: 3 Leccin 18
4


Sub consultas de mltiples columnas
Hasta ahora hemos escrito sub consultas de filas nicas y sub consultas de
mltiples filas donde solo una columna es obtenida por la sentencia SELECT
interna y estas son usadas para evaluar la expresin en la sentencia SELECT
padre. Si quieres comparar dos o ms columnas, debemos escribir una
clusula WHERE compuesta usando operadores lgicos. El uso de sub
consultas de mltiples columnas, puede combinar condiciones WHERE
duplicadas en una simple clusula WHERE.

Sintaxis:


La grfica anterior ilustra como los valores de MANAGER_ID y
DEPARTMEN_ID de la consulta principal son inicialmente comparadas con los
valores de MANAGER_ID y DEPARTMENT_ID recuperados por la
subconsulta. Desde que el nmero de columnas que son inicialmente
comparadas son mas de una, el ejemplo se califica como una sub consulta de
mltiples columnas.

Comparaciones en pares contra comparaciones no pares
La comparacin de columnas en una sub consulta de mltiples columnas
puede ser una comparacin par o una comparacin no par.

Parcial II: 3 Leccin 18
5

En el ejemplo siguiente, una comparacin par es ejecutada en la clusula
WHERE. Cada fila candidata en la sentencia SELECT debe tener ambas las
mismas columnas MANAGER_ID y DEPARTMENT_ID como el empleado con
el EMPLOYEE_ID 178 o 174.

Una sub consulta de mltiples columnas puede tambin ser una comparacin
no par. En una comparacin no par, cada columna de la clusula WHERE de la
sentencia SELECT padre es individualmente comparada con mltiples valores
recuperados por la sentencia SELECT interna. Las columnas individuales
pueden corresponder con algunos de los valores recuperados por la sentencia
SELECT interna. Pero en conjunto, todas las condiciones mltiples de la
sentencia SELECT principal deben ser satisfechas para las filas a ser
desplegadas. En los siguientes ejemplos se ilustra una comparacin no par.


Sub consulta con comparacin par
El ejemplo anterior es una sub consulta de mltiples columnas puesto que la
sub consulta obtiene ms de una columna. Este compara los valores en las
columnas MANAGER_ID y DEPARTMENT_ID de cada fila en la tabla
EMPLOYEES con los valores en las columnas MANAGER_ID y
DEPARTMENT_ID para los empleados con EMPLOYEE_ID 178 o 174.

Primero, la sub consulta que recupera los valores de MANAGER_ID y
DEPARTMENT_ID para los empleados con EMPLOYEE_ID 178 o 174 es
ejecutada. Estos valores son comparados con las columnas MANAGER_ID y
DEPARTMENT_ID de cada fila en la tabla EMPLOYEES. Si los valores
corresponden, la fila es desplegada. En el resultado, los registros de los
empleados con EMPLOYEE_ID 178 o 174 no sern desplegados. El resultado
de la consulta anterior es:


Parcial II: 3 Leccin 18
6


Sub consulta con comparacin no par
El ejemplo muestra una comparacin de columnas no par. Esta despliega
EMPLOYEE_ID, MANAGER_ID y DEPARTMENT_ID de todos los empleados
cuyo MANAGER_ID corresponda con alguno de los MANAGER_IDs de los
empleados cuyo EMPLOYEE_ID sea 174 o 141 y DEPARTMENT_ID
corresponda con alguno de los DEPARTMENT_IDs de los empleados cuyo
EMPLOYEE_ID sea 174 o 141.

Primero, la sub consulta se ejecuta para recuperar los valores de
MANAGER_ID para aquellos empleados con el EMPLOYEE_ID 174 o 141. De
forma similar, la segunda sub consulta se ejecuta para recuperar los valores de
DEPARTMENT_ID para los empleados con EMPLOYEE_ID 174 o 141. Los
valores recuperados de las columnas MANAGER_ID y DEPARTMENT_ID son
comparados con las columnas MANAGER_ID y DEPARTMENT_ID para cada
fila en la tabla EMPLOYEES. Si la columna MANAGER_ID de la fila en la tabla
EMPLOYEES corresponde con alguno de los valores de MANAGER_ID
recuperados por la sub consulta interna y la columna DEPARTMENT_ID de la
fila en la tabla EMPLOYEES corresponde con alguno de los valores de
DEPARTMENT_ID recuperado por la segunda sub consulta, el registro es
desplegado. El resultado de la consulta anterior se muestra a continuacin.



Parcial II: 3 Leccin 18
7


Usando una sub consulta en la clusula FROM
Se puede usar una sub consulta en la clusula FROM de una sentencia
SELECT, el cul es muy similar al manejo de las vistas que hemos usado. Una
sub consulta en la clusula FROM de una sentencia SELECT es tambin
llamada una vista en lnea. Una sub consulta en una clusula FROM de una
sentencia SELECT define un origen de datos para esa sentencia SELECT en
particular, y solo esa sentencia SELECT. El ejemplo anterior despliega el
nombre de los empleados, salarios, nmero de departamentos y salario
promedio para todos los empleados que ganen mas que el salario promedio de
su departamento. La sub consulta en la clusula FROM es llamada b, y la
consulta exterior hace referencia a la columna SALAVG usando este alias.

Sub consultas escalares en SQL
Una sub consulta que obtiene exactamente un valor de una columna de una fila
es tambin llamada sub consulta escalar. Sub consultas de mltiples columnas
escritas para comparar dos o ms columnas, usando una clusula WHERE
compuesta y operadores lgicos, no pueden ser calificados como sub consultas
escalares.
El valor de una expresin en una sub consulta escalar es el valor del elemento
de la lista seleccionado de la sub consulta. Si la sub consulta obtiene 0 filas, el
valor de la expresin de la sub consulta escalar es nulo. Si la sub consulta
obtiene ms de una fila, el servidor de Oracle muestra un error. El servidor de
Oracle siempre tiene el apoyo para usar una sub consulta escalar en una
sentencia SELECT. El uso de una sub consulta escalar ha sido mejorado en
Oracle9i. Ahora se pueden usar sub consultas escalares en:
Condiciones y parte de expresiones de funciones DECODE y CASE
Todas las clusulas del SELECT excepto GROUP BY
En el lado izquierdo del operador en una clusula SET y WHERE de una
sentencia UPDATE

Parcial II: 3 Leccin 18
8

Sin embargo, las sub consultas escalares no son expresiones vlidas en los
siguientes lugares:
Como valor por defecto para columnas y expresiones para clusters
En la clusula RETURNING de sentencias DML
Como base de una funcin base indexada
En la clusula GROUP BY, constraints CHECK, condiciones WHEN
Clusulas HAVING
En clusulas START WITH y CONNECT BY
En sentencias que no son relacionados con consultas, como CREATE
PROFILE


Ejemplo de sub consultas escalares
En la primer consulta del ejemplo anterior se demuestra que las sub consultas
escalares pueden ser usadas en expresiones CASE. La consulta interna
obtiene el valor de 20, el cul el DEPARTMENT_ID del departamento cuya
LOCATION_ID es 1800. La expresin CASE en la consulta externa usa el
resultado de la consulta interna para desplegar el nmero de empleado,
nombre y valor de Canada o USA, dependiendo de si DEPARTMENT_ID del
registro recuperado por la consulta externa es 20 o no.

El resultado de esta consulta es:



Parcial II: 3 Leccin 18
9

En el segundo ejemplo se demuestra como la sub consulta escalar puede ser
usada en la clusula ORDER BY. El ejemplo ordena el resultado con base en
el DEPARTMENT_NAME por la correspondencia del DEPARTMENT_ID de la
tabla EMPLOYEES con el DEPARTMENT_ID de la tabla DEPARTMENTS.
Esta comparacin es hecha por una sub consulta escalar en la clusula
ORDER BY. El resultado se muestra a coninuacin:



El segundo ejemplo usa una sub consulta correlacionada. En una sub consulta
correlacionada, la sub consulta hace referencia a una columna de una tabla
referida en una sentencia padre. Las sub consultas correlacionadas son
explicadas en el siguiente tema.

Parcial II: 3 Leccin 18
10


Sub consulta correlacionada
El servidor de Oracle ejecuta sub consultas correlacionadas cuando la sub
consulta se relaciona con una columna de una tabla referida en la sentencia
padre. Una sub consulta correlacionada es evaluada una vez para cada fila
procesada por la sentencia padre. La sentencia padre puede ser una sentencia
SELECT, UPDATE o DELETE.

Sub consultas anidadas contra sub consultas correlacionadas
Con una sub consulta anidada normal, la consulta SELECT interna corre
primero y se ejecuta una sola vez, obteniendo valores para ser usados en la
consulta principal. Una sub consulta correlacionada, sin embargo, se ejecuta
una vez para cada fila candidata considerada por la consulta externa. En otras
palabras, la consulta interna es la gua para la consulta externa.

Ejecucin de sub consultas anidadas
La consulta interna se ejecuta primero y encuentra un valor
La consulta externa se ejecuta una vez, usando el valor de la consulta
interna

Ejecucin de sub consultas correlacionadas
Recibe una fila candidata (obtenida por la consulta externa)
Ejecuta la consulta interna usando el valor de la fila candidata
Usa los valores resultantes de la consulta interna para calificar o
descalificar la fila candidata
Se repite hasta terminar con las filas candidatas

Parcial II: 3 Leccin 18
11



Una sub consulta correlacionada es un camino de lectura de cada fila en una
tabla y la comparacin de valores en cada fila contra los datos relacionados. Es
usado cuantas veces una sub consulta deba retornar un resultado diferente o
conjunto de resultados para cada fila candidata considerada por la consulta
principal. En otras palabras, utilice una consulta correlacionada para resolver
una pregunta de mltiples partes cuya respuesta dependa del valor de cada fila
procesada por la sentencia padre.
El servidor de Oracle ejecuta una sub consulta correlacionada cuando la sub
consulta hace referencia a una columna de la consulta padre.

Nota: Puedes usar los operadores ANY y ALL en una sub consulta
correlacionada.

Parcial II: 3 Leccin 18
12


Usando sub consultas correlacionadas
En el ejemplo anterior se determina que empleados ganan ms del salario
promedio de su departamento. En este caso, la sub consulta correlacionada
especficamente calcula el salario promedio para cada departamento.
Puesto que ambas consultas, la interna y la externa utilizan la tabla
EMPLOYEES en la clusula FROM, un alias es utilizado para la tabla
EMPLOYEES en la sentencia SELECT externa, para mayor claridad. No
solamente el uso del alias hace que la sentencia SELECT sea de mejor lectura,
pero sin ese alias la consulta puede no trabajar apropiadamente, debido a que
la sentencia interna puede no ser capaz de distinguir la columna de la tabla
interna de la columna de la tabla externa.

Parcial II: 3 Leccin 18
13



En el ejemplo se despliegan los detalles de aquellos empleados que hayan
cambiado de puesto mnimo dos veces. El servidor de Oracle evala la
consulta correlacionada como sigue:
1. Se selecciona una fila de la tabla especificada en la consulta externa.
Esta puede ser denominada la fila candidata actual.
2. Se almacena el valor de la columna referenciada en la sub consulta de
la fila candidata. (En el ejemplo, la columna referenciada en la sub
consulta es E. EMPLOYEE_ID)
3. Se ejecuta la sub consulta con el valor de la condicin referenciada de la
fila candidata de la consulta externa. (En el ejemplo, la funcin de grupo
COUNT(*) es evaluado con base en el valor de la columna
E.EMPLOYEE_ID obtenida en el paso 2.)
4. Se evala la clusula WHERE de la consulta externa en base al
resultado de la sub consulta ejecutada en el paso 3. Esto determina si la
fila candidata es desplegada. (En el ejemplo, el nmero de veces que un
empleado ha sido cambiado de puesto, evaluado por la sub consulta, es
comparado con el valor 2 en la clusula WHERE de la consulta externa.
Si la condicin es satisfecha, el registro del empleado es mostrado.)
5. Se repite el procedimiento para las siguientes filas candidatas de la
tabla, y as hasta que todas las filas en la tabla hayan sido procesadas.

La correlacin es establecida por el uso de un elemento de la consulta externa
en la sub consulta. En este ejemplo, la correlacin es establecida por la
sentencia EMPLOYEE_ID = E.EMPLOYEE_ID en donde se compara
EMPLOYEE_ID de la tabla en la sub consulta con el EMPLOYEE_ID de la
tabla de la consulta externa.

Parcial II: 3 Leccin 18
14

Operador EXISTS
Cuando anidamos sentencias SELECT, todos los operadores lgicos son
vlidos. En suma, se puede usar el operador EXISTS. Este operador es
frecuentemente usado en sub consultas correlacionadas para verificar cuando
un valor recuperado por la consulta externa existe en el conjunto de resultados
obtenidos por la consulta interna. Si la sub consulta obtiene al menos una fila,
el operador obtiene el valor TRUE. Si el valor no existe, se obtiene el valor
FALSE. Consecuentemente, NOT EXISTS verifica cuando un valor recuperado
por la consulta externa no es parte del conjunto de resultados obtenidos por la
consulta interna.


Usando el operador EXISTS
El operador EXISTS se asegura que la bsqueda en la consulta interna no
continu cuando al menos una correspondencia sea encontrada para el jefe y
nmero de empleado en la condicin:

WHERE manager_id = outer.employee_id.

Note que el SELECT de la consulta interna no necesita obtener un valor
especfico, de tal manera que una constante puede ser seleccionada. Desde el
punto de vista de la ejecucin, es ms rpido seleccionar una constante que
una columna.

Nota: Teniendo EMPLOYEE_ID en la clusula SELECT de la consulta interna
causa una bsqueda de esa columna en la tabla. Remplazando esta por una
literal X, o cualquier constante, mejora el desempeo. Esto es ms eficiente
que el uso del operador IN.

Parcial II: 3 Leccin 18
15

Un operador IN puede ser usado como una alternativa para un operador
EXISTS, como se ve en el siguiente ejemplo:



Usando el operador NOT EXISTS



Solucin alternativa
Un operador NOT IN puede ser utilizado como una alternativa para el operador
NOT EXISTS, como se muestra en el siguiente ejemplo:



Sin embargo, NOT IN evala a FALSE si algn miembro del conjunto de
resultados es un valor nulo. Por consiguiente, las consultas pueden no obtener
algunas filas si estas filas en la tabla DEPARTMENTS no satisfacen la
condicin WHERE.

Parcial II: 3 Leccin 18
16


UPDATE Correlacionado
En el caso de la sentencia UPDATE, se puede usar una sub consulta
correlacionada para actualizar filas en una tabla con base a las filas de otra
tabla.



En el ejemplo se modifica la tabla EMPLOYEES con la adicin de la columna
DEPARTMENT_NAME, para almacenar el nombre del departamento y poblar
la tabla con el uso del UPDATE correlacionado.

Parcial II: 3 Leccin 18
17

Problema en la sentencia
Use una sub consulta correlacionada para actualizar filas en la tabla
EMPLOYEES basndose en las filas de la tabla REWARDS:



Este ejemplo usa la tabla REWARDS. La tabla REWARDS tiene la columna
EMPLOYEE_ID, PAY_RAISE y PAYRAISE_DATE. Cada ves que un empleado
tiene un aumento de sueldo, un registro con el detalle del empleado, la
cantidad de incremento y la fecha es insertada en esta tabla. La tabla
REWARDS puede contener ms de un registro para un empleado. La columna
PAYRAISE_DATE es utilizada para identificar el aumento ms reciente recibido
por un empleado.
En el ejemplo, la columna SALARY en la tabla EMPLOYEES es actualizada
para reflejar el ltimo aumento recibido para el empleado. Esto es realizado
incrementando al salario actual el incremento otorgado.

Parcial II: 3 Leccin 18
18


DELETE Correlacionado
En el caso de la sentencia DELETE, se puede usar una sub consulta
correlacionada para eliminar solo aquellas filas que tambin existan en otra
tabla. Si decides que debes mantener solo los ltimos cuatro registros
histricos de la tabla JOB_HISTORY, entonces cuando un empleado sea
transferido a su quito puesto, debes de eliminar las filas mas antiguas. El
siguiente cdigo muestra como se puede usar un DELETE correlacionado:




Parcial II: 3 Leccin 18
19


Ejemplo
Dos tablas son usadas en este ejemplo:
La tabla EMPLOYEES, que proporciona los detalles de los empleados
actuales
La tabla EMP_HISTORY, que proporciona los detalles de los empleados
anteriores

EMP_HISTORY contiene los datos de los empleados anteriores, sin embargo
esto podra ser incorrecto si el mismo empleado existe en ambas tablas. El
ejemplo anterior elimina los registros incorrectos con el uso de una sub
consulta correlacionada.

Clusula WITH
Usando la clusula WITH, se puede definir un bloque de una consulta antes de
que esta sea usada. La clusula WITH (formalmente conocida como
subquery_factoring_clausula clusula de sub consulta factorizada) habilita la
reutilizacin del mismo bloque de la consulta en una sentencia SELECT
cuando esto ocurre en mas de una ocasin en una consulta compleja. Esto es
particularmente til cuando una consulta tiene muchas referencias al mismo
bloque de una consulta y se tienen asociaciones y agrupaciones.

Usando la clusula WITH, se puede reutilizar la misma consulta cuando es de
alto costo evaluar el bloque de la consulta y ocurre ms de una vez en una
consulta compleja. Usando la clusula WITH, el servidor de Oracle recupera los
resultados de un bloque de la consulta y los almacena en un tablespace
temporal del usuario. Esto puede mejorar el desempeo.

Parcial II: 3 Leccin 18
20

Beneficios de la clusula WITH
Hace que la consulta sea fcil de leer
Evala una clusula una sola vez, aun si esta aparece muchas veces en
la consulta, por esta razn aumenta el desempeo

Ejemplo de la clusula WITH

Problema
Usando la clusula WITH, escriba una consulta para desplegar el nombre del
departamento y el salario total para aquellos departamentos cuyo salario total
es mayor que el salario promedio de los departamentos.

Este problema requiere de los siguientes clculos intermedios:
1. Calcular el salario total para cada departamento y almacenar el
resultado usando la clusula WITH
2. Calcular el salario promedio de todos los departamentos y almacenar el
resultado usando la clusula WITH
3. Comparar el salario total calculado en el paso 1 con el salario promedio
calculado en el paso 2. Si el salario total de un departamento en
particular es mayor que el salario total de todos los departamentos,
despliegue el nombre del departamento y el salario total para ese
departamento.

La solucin se muestra a continuacin:



El cdigo SQL anterior un ejemplo de la situacin en la cual se puede mejorar
el desempeo y escribir sentencias SQL de forma ms clara con el uso de la
clusula WITH. La consulta crea los nombres de consulta DEPT_COSTS y
AVG_COST que son usadas en el cuerpo de la consulta principal.
Internamente, la clusula WITH es determinada como una vista en lnea o una
tabla temporal. El decidir optimizar la solucin apropiada depende del costo o
beneficio del almacenamiento temporal de los resultados con la clusula WITH.

Parcial II: 3 Leccin 18
21

Nota: Una sub consulta en la clusula FROM de una sentencia SELECT es
tambin llamada vista en lnea.

El resultado generado por cdigo SQL anterior muestra lo siguiente:



Consideraciones para el uso de la clusula WITH
Esta es usada solo con sentencias SELECT
Un nombre de consulta es visible para todos los elementos dentro del
bloque WITH (incluyendo sus bloques de sub consultas)
Cuando el nombre de una consulta es el mismo que el nombre de una
tabla, el anlisis se hace de adentro hacia fuera, el nombre del bloque
de la consulta toma precedencia sobre el nombre de la tabla
La clusula WITH puede mantener ms de una consulta. Cada consulta
es entonces separada por una coma.

Resumen
En este captulo se ha revisado lo siguiente:
Una sub consulta de mltiples columnas obtiene mas de una columna
Las comparaciones de mltiples columnas pueden ser en pares o no
pares.
Una sub consulta de mltiples columnas puede tambin ser usada en la
clusula FROM de una sentencia SELECT
Las sub consultas escalares han sido mejoradas en Oracle9i
Las sub consultas correlacionadas son tiles cuando una sub consulta
debe obtener un resultado diferente por cada fila candidata
El operador EXISTS es un operador Boleano que verifica la presencia de
un valor
Las sub consultas correlacionadas pueden ser usadas con sentencias
SELECT, UPDATE y DELETE
Se puede usar la clusula WITH para usar el mismo bloque de consulta
en una sentencia SELECT cuando esta sea necesaria en ms de una
ocasin.

También podría gustarte