Sie sind auf Seite 1von 21

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 1

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.

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.

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.

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:

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.

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

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:

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.

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

10

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.

11

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.

12

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.

13

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.

14

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.

15

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.

16

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.

17

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:

18

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.

19

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. 20

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.

21

Das könnte Ihnen auch gefallen