You are on page 1of 25

4.

- Obteniendo datos de mltiples tablas


Objetivos del captulo Escribir sentencias SQL para obtener datos de ms de una tabla utilizando asociaciones de igualdad y desigualdad. Ver datos que generalmente no se encuentran en una condicin de asociacin con el uso de asociaciones externas (outer join). Asociacin de una tabla a si misma con el uso del self join.

Datos de mltiples tablas En algunas ocasiones se requieren datos de ms de una tabla. En la imagen anterior el reporte muestra datos de dos tablas separadas. El identificador del empleado existe en la tabla EMPLOYEES El identificador del departamento existe las tablas de EMPLOYEES y DEPARTMENTS El identificador de localizacin existe en la tabla DEPARTMENTS Para producir el reporte, se necesita asociar las tablas EMPLOYEES y DEPARTMENTS y acceder a los datos de ambas. Producto cartesiano Cuando una condicin join (asociacin) es invlida u omitida completamente, el resultado es un producto cartesiano, en el que todas las combinaciones de filas son mostrada. Todas las filas de la primera tabla son asociadas con las filas de la segunda tabla. Un producto cartesiano tiende a generar un largo nmero de filas, y el resultado es raramente utilizado. Siempre se debe incluir una condicin join vlida en una

clusula WHERE, a menos que se tenga una necesidad especfica para combinar todas las filas de todas las tablas. El producto cartesiano es til para algunas pruebas cuando se necesita generar un largo nmero de filas simulando un razonable nmero de datos.

Un Producto cartesiano es generado si una condicin JOIN (asociacin) es omitida. En la imagen anterior se muestra el apellido y nombre del departamento de las tablas EMPLOYEES y DEPARTMENTS. Puesto que no se ha especificado una clusula WHERE, todas las filas (20) de la tabla EMPLOYEES son asociadas con todas las filas (8) de la tabla DEPARTMENTS, en consecuencia 160 filas son mostradas.

Tipos de JOINS La base de datos Oracle9i ofrece la sintaxis JOIN de SQL:1999. Antes de la puesta en marcha de los productos 9i, la sintaxis del JOIN era diferente al estndar de ANSI. En el nuevo SQL: 1999 la sintaxis JOIN no ofrece ningn funcionamiento benfico con respecto a la sintaxis JOIN propiedad de Oracle. Definiendo JOINS

Cuando los datos de ms de una tabla de una base de datos son requeridos, una condicin join es utilizada. Las filas en una tabla pueden ser asociadas con las filas de otra tabla de acuerdo a los valores comunes existentes en sus correspondientes columnas, esto es usualmente una llave primaria (primary key) y una llave fornea (foreing key). Para desplegar datos de dos o ms tablas relacionadas. Se escribe una simple condicin join en la clusula WHERE. En la sintaxis: table1.column table1.column1 = table2.column2

denota la tabla y columna donde el dato ser recuperado es la condicin join (o relacin) del conjunto de tablas

Normas a seguir Cuando escribes una sentencia SELECT que asocia tablas, se precede al nombre de la columna con el nombre de la tabla para una mejor claridad y resaltar el acceso a la base de datos. Si el mismo nombre de columna aparece en ms de una tabla, el nombre de la columna debe ser antecedido con el nombre de la tabla. La asociacin con n tablas en su conjunto, requiere un mnimo de n-1 condiciones de asociacin. Por ejemplo, un join o asociacin con 4 tablas, requiere de al menos 3 asociaciones. Esta regla puede no aplicarse si la tabla tiene una llave primaria concatenada, en estos casos ms de una columna es requerida para identificar de forma nica a cada columna.

Equijoins Para determinar el nombre del departamento de un empleado, se compara el valor de la columna DEPARTMENT_ID de la tabla EMPLOYEES con el valor de la columna DEPARTMENT_ID de la tabla DEPARTMENTS. La relacin entre las tablas EMPLOYEES y DEPARTMENTS es un equijoinesto es, los valores en la columna DEPARTMENT_ID en ambas tablas deben ser iguales. Frecuentemente este tipo de asociaciones involucra una llave primaria y una llave fornea. Nota: Los equijoins tambin son llamados simple joins o inner joins.

Recuperando registros con equijoins En el ejemplo anterior: La clusula SELECT especifica el nombre de las columnas a recuperar o employees.employee_id, employees.last_name y employees.department_id son columnas de la tabla EMPLOYEES o departments.department_id y departments.location_id son columnas de la tabla DEPARTMENTS La clusula FROM especifica las tablas de la base de datos que se deben acceder: o Tabla EMPLOYEES o Tabla DEPARTMENTS La clusula WHERE como las tablas se relacionaran o asociaran: o EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID Puesto que la columna DEPARTMENT_ID es comn en ambas tablas, esta debe ser antecedida del nombre de la tabla para evitar ambigedades.

Condiciones adicionales de bsqueda De forma adicional al join, se puede tener un criterio en la clusula WHERE para restringir las filas bajo las consideraciones de una o ms tablas. Por ejemplo, para desplegar el nmero de departamento y nombre de departamento del empleado Matos, se necesita de una condicin adicional en la clusula WHERE.

Cualificando columnas ambiguas Se necesitan cualificar el nombre de las columnas en la clusula WHERE con el nombre de la tabla para evitar ambigedad. Sin el prefijo de la tabla, la columna DEPARTMENT_ID podra ser de la tabla DEPARTMENTS o EMPLOYEES. Es necesario agregar el prefijo de la tabla para ejecutar su consulta. Si no existen columnas con nombres comunes entre las tablas, no es necesario cualificar las columnas. Sin embargo, el uso del prefijo mejora el desempeo, puesto que se le indica al servidor Oracle exactamente la columna a buscar. El requerimiento para cualificar nombres de columnas ambiguas es tambin aplicable para columnas que pueden ser ambiguas en otras clusulas, como la clusula SELECT o la clusula ORDER BY.

Alias de tablas Cualificar el nombre de columnas con el nombre de la tabla puede ser muy tardado, particularmente si los nombres de las tablas son largos. Se puede hacer uso de alias para tablas en lugar del nombre de la tabla. De la misma forma que se da un alias a una columna con otro nombre, un alias de tabla le otorga otro nombre a la misma. Los alias de tablas ayudan a mantener el cdigo SQL ms pequeo y usar menos memoria. Note como en el ejemplo, el alias de una tabla es identificado en la clusula FROM. El nombre de la tabla es especificado en su totalidad, seguido por un espacio y el nombre del alias. La tabla EMPLOYEES tiene el alias e y la tabla DEPARTMENTS el alias d. Normas Los alias de tablas pueden tener ms de 30 caracteres, pero es mejor que sean cortos Si un alias de tabla es usado para una tabla en particular en la clusula FROM, entonces este alias debe ser substituido en por toda la sentencia SELECT El alias debe ser significativo El alias es vlido solamente para la sentencia SELECT actual

Condiciones adicionales de bsqueda En algunas ocasiones se requiere ms de dos tablas. Por ejemplo, mostrar el apellido, nombre de departamento y ciudad para cada empleado, se necesita asociar las tablas EMPLOYEES, DEPARTMENTS y LOCATIONS.

Non-Equijoins Un non-equijoin es un join conteniendo alguna otra condicin diferente a un operador de igualdad. La relacin entre las tablas EMPLOYEES y JOB_GRADES es un ejemplo de un non-equijoin. Una relacin entre estas dos tablas es que la columna SALARY de la tabla EMPLOYEES puede encontrarse entre las columnas LOWEST_SALARY y HIGHEST_SALARY de la tabla JOB_GRADES. La relacin es obtenida usando otro operador diferente al (=).

En el ejemplo anterior se crea un no-equijoin para evaluar la clasificacin de salario de los empleados. El salario debe estar entre algn par de rangos altos y bajos. Es importante notar que todos los empleados aparecen exactamente desde que la consulta es ejecutada. Los empleados no se repiten en la lista. Existen dos razones para esto: Note que las filas de la tabla JOB_GRADE contienen clasificaciones que se superponen. Esto es, el salario para un empleado puede estar

solamente entre los valores altos y bajos de una fila en la tabla SALARY_GRADE. Todos los salarios de los empleados se encuentran en los lmites provistos por la tabla JOB_GRADE. Esto es, no se tienen empleados que ganen menos que el valor contenido en la columna LOWEST_SAL o ms que el valor contenido en la columna HIGHEST_SAL.

Nota: Otras condiciones como <= y >= pueden ser utilizadas, pero es mas sencillo el BETWEEN. Recuerde especificar primeramente el rango menor que el mayor en la clusula BETWEEN. Los alias de tablas han sido utilizados en el ejemplo por razones de desempeo, no por un posible caso de ambigedad.

Outer Joins Obteniendo registros con comparaciones no directas por medio de Outer Joins Si una fila no cumple una condicin Join, esta fila no aparecer en el resultado de la consulta. Por ejemplo en la condicin equijoin de las tablas EMPLOYEES y DEPARTMENTS, El empleado Grant no aparece porque no existe un valor de departamento para l en la tabla EMPLOYEES. Por lo que en lugar de ver 20 empleados en el resultado, slo se muestran 19.

Usando Outer Joins para obtener registros sin una comparacin directa La ausencia de filas puede ser obtenida si un operador outer join es utilizado en la condicin join. El operador es una smbolo positivo encerrado entre parntesis (+), y es colocado a un lado del join que es deficiente en informacin. Este operador tiene el efecto de crear una o ms filas nulas, para el cual una o ms filas de una tabla no deficiente pueda ser asociada. En la sintaxis: table1.column = table2.column (+)

Es la condicin que asocia (o relaciona) las tablas. Es el smbolo outer join, que puede ser colocado a un lado de la condicin de la clusula WHERE, pero no en ambos lados. (Coloque el smbolo outer join seguido del nombre de la columna de la tabla con deficiencia de informacin)

En el ejemplo anterior se muestran los apellidos, departamentos y nombres. El departamento de contratacin no tiene ningn empleado. El valor mostrado es vaci. Restricciones del Outer Join El operador outer join puede aparecer en solo un lado de la expresin en el lado que tenga ausencia de informacin. Esto regresa aquellas filas de una tabla que no tenga una correspondencia con la otra tabla. Una condicin que involucra un outer join no puede utilizar el operador IN o ser vinculado con otra condicin por el operador OR.

Self Joins Asociando una tabla a si mismo En algunas ocasiones es necesario asociar una tabla a si mismo. Para encontrar el nombre del jefe de cada empleado, se requiere asociar la tabla EMPLOYEES con si misma o ejecutar un self join. Por ejemplo para encontrar el nombre del jefe de Whalen, se necesita: Encontrar a Whalen en la tabla EMPLOYEES viendo la columna LAST_NAME. Encontrar el nmero del jefe de Whalen viendo la columna MANAGER_ID. El nmero del jefe de Whalen es 101. Encontrar el nombre del jefe con EMPLOYEE_ID 101 viendo la columna LAST_NAME. El empleado Kochhar es el nmero 101. entonces Kochhar es jefe de Whalen. En este proceso, necesitamos ver la tabla dos veces. La primera ocasin para encontrar las columnas LAST_NAME y MANAGER_ID de Whalen. La segunda

vez para buscar el valor 101 en la columna EMPLOYEE_ID y encontrar a Kochhar en la columna LAST_NAME.

En el ejemplo anterior el join de la tabla EMPLOYEES se realiza a s mismo. Para simular dos tablas en la clusula FROM, hay dos alias llamados w y m, de la misma tabla EMPLOYEES. En este ejemplo, la clusula WHERE contiene el join de esta manera donde el nmero del jefe del empleado es igual al nmero del empleado asignado al jefe.

Joins a tablas utilizando la sintaxis SQL 1999 Definiendo joins Utilizando la sintaxis SQL 1999, se puede obtener los mismos resultados que hemos visto en los temas anteriores. En la sintaxis: table1.column CROSS JOIN NATURAL JOIN JOIN table USING column_name JOIN table ON table1.column_name = table2.column_name LEFT/RIGHT/FULL OUTER Creando Cross Joins Denota la tabla y columna donde el dato es recuperado Regresa un producto cartesiano de dos tablas Joins de dos tablas basado en el mismo nombre de columna Ejecuta un equijoin basado en el nombre de la columna Ejecuta un equijoin basado en la condicin de la clusula ON

El ejemplo anterior obtiene los mismos resultados que el siguiente:

Creando Natural Joins No era posible hacer un join sin especificar explcitamente las columnas de las tablas en versiones previas de Oracle. En Oracle9i esto es posible, permitiendo que el join sea automticamente realizado basndose en las columnas de las dos tablas que tienen el mismo nombre y tipo de dato, usando la palabra reservada NATURAL JOIN. Nota: El join puede ocurrir en columnas que tengan el mismo nombre y tipo de dato en ambas tablas. Si las columnas tienen el mismo nombre, pero diferente tipo de datos, entonces la sintaxis NATURAL JOIN devuelve un error. Recuperando registros con Natural Joins

En el ejemplo anterior, la tabla LOCATIONS es asociada con la tabla DEPARTMENT por la columna LOCATION_ID, que es la nica columna con el mismo nombre en ambas tablas. Si otra columna comn estuviese presente, el join puede usarla.

Equijoins El natural join puede tambien ser escrito como un equijoin: SELECT department_id, department_name, departments.location_id, city FROM departments, locations WHERE departments.location_id = locations.location_id; Natural Joins con una clusula WHERE Las restricciones adicionales en un natural join son implementadas por el uso de la clusula WHERE. En el ejemplo siguiente se limitan las filas resultantes con un nmero de departamento igual a 20 o 50. SELECT department_id, department_name, location_id, city FROM departments NATURAL JOIN locations WHERE department_id IN (20,50); La clusula USING El natural joins utiliza todas las columnas cuyos nombres y tipos de datos sean iguales para asociar las tablas. Las columnas referenciadas en la clusula USING no tienen que ser cualificadas (con el nombre de la tabla o alias) en cualquier lugar de la sentencia SQL. Por ejemplo, esta sentencia es vlida: SELECT l.city, d.department_name FROM locations l JOIN departments d USING (location_id) WHERE location_id = 1400; Esta sentencia es invlida porque LOCATION_ID es cualificado en la clusula WHERE: SELECT l.city, d.department_name FROM locations l JOIN departments d USING (location_id) WHERE d.location_id = 1400; ORA-25154: column part of USING clause cannot have qualifier

La misma restriccin aplica para el NATURAL JOINS. Por consiguiente las columnas deben tener el mismo nombre en ambas tablas teniendo que ser usadas sin ningn calificador.

En el ejemplo se muestra una asociacin de la columna DEPARTMENT_ID de las tablas EMPLOYEES y DEPARTMENTS, para as ver la localizacin donde el empleado trabaja. Tambin puede ser escrito como un equijoin:

La condicin ON Utilice la clusula ON para especificar una condicin join. Esto permite especificar una condicin join por separado de alguna condicin de bsqueda o filtrado en la clusula WHERE. Creando joins con la clusula ON La clusula ON puede ser utilizada para asociar columnas que tienen diferentes nombres:

El ejemplo anterior es un selfjoin de la tabla EMPLOYEE con si misma, basndose en las columnas EMPLOYEE_ID y MANAGER_ID. Three-Way Joins

Un Three-Way Join es un join de tres tablas. En la sintaxis SQL: 1999, los joins son ejecutados de izquierda a derecha as que el primer join que es ejecutado es EMPLOYEES JOIN DEPARTMENTS. La primera condicin join puede referenciar columnas en EMPLOYEES y DEPARTMENTS pero no puede referenciar columnas en LOCATIONS. La segunda condicin join puede referenciar columnas de las tres tablas. Tambin puede ser escrito como un Three-way equijoin:

INNER Vs OUTER Joins En SQL: 1999, el join de dos tablas regresa solamente las filas iguales esto es un INNER Join. Un join entre dos tablas que obtiene el resultado de un inner join como tambin las filas de tablas izquierdas o derechas no comparables es un left o right outer join. Un join entre dos tablas que obtiene el resultado de un inner join, como tambin el resultado de un left y right join es llamado un full outer join.

Comparando joins SQL:1999 con Oracle

Ejemplo de un LEFT OUTER JOIN

Esta consulta recupera todas las filas de la tabla EMPLOYEES, que es la tabla izquierda an sin no existen comparaciones con la tabla DEPARTMENTS. Esta consulta tambin puede escribirse de la siguiente forma:

Ejemplo de un RIGHT OUTER JOIN

Esta consulta recupera todas las filas de la tabla DEPARTMENTS, que es la tabla derecha an si no existen comparaciones con la tabla EMPLOYEES. Esta consulta tambin puede ser escrita de la siguiente manera:

Ejemplo de un FULL OUTER JOIN

Esta consulta todas las columnas de la tabla EMPLOYEES, an si no existen comparaciones con la tabla DEPARTMENTS. Tambin recupera todas las filas de la tabla DEPARTMENTS, aunque no se tengan comparaciones con la tabla EMPLOYEES.

Esta consulta no es posible realizarse utilizando simplemente condiciones outer joins, debido a la complejidad del resultado, slo se puede obtener por medio del operador UNION, como se muestra a continuacin:

Aplicando condiciones adicionales

Se pueden aplicar condiciones adicionales en la clusula WHERE. En el ejemplo se ejecuta un join de las tablas EMPLOYEES y DEPARTMENTS, y se agrega una condicin para que solo sean mostrados los empleados cuyo jefe sea igual a 149. Resumen Existen mltiples caminos para asociar tablas. Tipos de joins Equijoins Non-equijoins Outer joins Self joins Cross joins Natural joins Full u Outer joins

Prctica 4 Esta prctica pretende aportar experiencia en la extraccin de datos de ms de una tabla. 1. Escriba una consulta que despliegue el apellido, numero de departamento y nombre de departamento para todos los empleados.

2. Genere un nico listado de todos los puestos que hay en el departamento 80. incluya la localizacin del departamento en la consulta.

3. Escriba una consulta que muestre el apellido del empleado, nombre del departamento, identificador de la localizacin y ciudad de todos los empleados que tengan una comisin.

4. Despliegue el apellido y nombre del departamento para todos los empleados que tengan una a (minscula) en su apellido. Guarde la sentencia SQL en un archivo con el nombre lab4_4.sql

5. Escribe una consulta que despliegue el apellido, puesto y numero de departamento para todos los empleados que trabajan en Toronto

6. Despliegue el apellido y nmero de empleado junto con el apellido y numero de empleado de su jefe. Las columnas debern llamarse Employee, Emp#, Manager y Mgr# respectivamente. Guarde su sentencia en un archivo llamado lab4_6.sql

7. Modifica el lab4_6.sql para mostrar a todos los empleados incluyendo a King, el cul no tiene jefe. Ordena los resultados por el nmero de empleado y guarde la sentencia en el archivo lab4_7.sql

Si tiene tiempo, complete los siguientes ejercicios: 8. Cree una consulta que despliegue el apellido del empleado, nmero de departamento y todos los empleados quienes trabajen en el mismo departamento con cada determinado empleado. Agregue a cada columna un etiqueta apropiada

9. Muestre la estructura de la tabla JOB_GRADES. Elabore una consulta que despliegue el nombre, puesto, nombre de departamento, salario y categora de todos los empleados

Si tienes tiempo extra, realiza los siguientes ejercicios 10. Elabora una consulta que despliegue el nombre y fecha de contratacin de los empleados contratados despus del empleado Davies

11. Despliegue los nombres y fecha de contratacin de todos los empleados que fueron contratados antes que sus jefes, junto con el nombre y fecha de contratacin de sus jefes. Etiquete las columnas como Employee, Emp, Hired, Manager y Mgr Hired respectivamente

You might also like