Sei sulla pagina 1di 10

Consultas combinadas. JOINS Consultas combinadas.

Habitualmente cuando necesitamos recuperar la informacin de una base de datos nos encontramos con que dicha informacin se encuentra repartida en varias tablas, referenciadas a travs de varios cdigos. De este modo si tuvieramos una tabla de ventas con un campo cliente, dicho campo contendra el cdigo del cliente de la tabla de cliente. Sin embargo est forma de almacenar la informacin no resulta muy util a la hora de consultar los datos. SQL nos proporciona una forma facil de mostrar la informacin repartida en varias tablas, las consultas combinadas o JOINS. Las consultas combinadas pueden ser de tres tipos: Combinacin interna Combinacin externa Uniones [arriba]

Combinacin interna. La combinacin interna nos permite mostrar los datos de dos o ms tablas a travs de una condicin WHERE. Si recordamos los ejemplos de los capitulos anteriores tenemos una tabla de coches, en la que tenemos referenciada la marca a travs del cdigo de marca. Para realizar la consulta combinada entre estas dos tablas debemos escribir una consulta SELECT en cuya clasula FROM escribiremos el nombre de las dos tablas, separados por comas, y una condicin WHERE que obligue a que el cdigo de marca de la tabla de coches sea igual al cdigo de la tabla de marcas. Lo ms sencillo es ver un ejemplo directamente:

SELECT tCoches.matricula, tMarcas.marca, tCoches.modelo, tCoches.color, tCoches.numero_kilometros, tCoches.num_plazas FROM tCoches, tMarcas WHERE tCoches.marca = tMarcas.codigo

La misma consulta de forma "visual" ...

Demonos cuenta que hemos antepuesto el nombre de cada tabla a el nombre del campo, esto no es obligatorio si los nombres de campos no se repiten en las tablas, pero es acondajable para evitar conflictos de nombres entre campos. Por ejemplo, si para referirnos al campo marca no anteponemos el nombre del campo la base de datos no sabe si queremos el campo marca de la tabla tCoches, que contiene el cdigo de la marca, o el campo marca de la tabla tMarcas, que contiene el nombre de la marca. Otra opcin es utilizar la clusula INNER JOIN. Su sintaxis es identica a la de una consulta SELECT habitual, con la particularidad de que n la clusula FROM slo aparece una tabla o vista, aadiendose el resto de tablas a travs de clusulas INNER JOIN .

SELECT [ALL | DISTINCT ] <nombre_campo> [{,<nombre_campo>}] FROM <nombre_tabla> [{INNER JOIN <nombre_tabla> ON <condicion_combinacion>}] [WHERE <condicion> [{ AND|OR <condicion>}]] [GROUP BY <nombre_campo> [{,<nombre_campo >}]] [HAVING <condicion>[{ AND|OR <condicion>}]] [ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC] [{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]

El ejemplo anterior escrito utilizando la clausula INNER JOIN quedaria de la siguiente manera:

SELECT tCoches.matricula, tMarcas.marca, tCoches.modelo, tCoches.color, tCoches.numero_kilometros, tCoches.num_plazas FROM tCoches INNER JOIN tMarcas ON tCoches.marca = tMarcas.codigo

La clusula INNER JOIN permite separar completamente las condiciones de combinacin con otros criterios, cuando tenemos consultas que combinan nueve o diez tablas esto realmente se agradece. Sin embargo muchos programadores no son amigos de la clusula INNER JOIN, la razn es que uno de los principales gestores de bases de datos, ORACLE, no la soportaba. Si nuestro porgrama debia trabajar sobre bases de datos ORACLE no podiamos utilizar INNER JOIN. A partir de la version ORACLE 9i oracle soporta la clusula INNER JOIN. [arriba]

Combinacin Externa La combinacin interna es excluyente. Esto quiere decir que si un registro no cumple la condicin de combinacin no se incluye en los resultados. De este modo en el ejemplo anterior si un coche no tiene grabada la marca no se devuelve en mi consulta. Segn la naturaleza de nuestra consulta esto puede ser una ventaja , pero en otros casos significa un serio problema. Para modificar este comportamiento SQL pone a nuestra disposicin la combinacin externa. La combinacin externa no es excluyente. La sintaxis es muy parecida a la combinacin interna,

SELECT [ALL | DISTINCT ] <nombre_campo> [{,<nombre_campo>}] FROM <nombre_tabla> [{LEFT|RIGHT OUTER JOIN <nombre_tabla> ON <condicion_combinacion>}] [WHERE <condicion> [{ AND|OR <condicion>}]] [GROUP BY <nombre_campo> [{,<nombre_campo >}]] [HAVING <condicion>[{ AND|OR <condicion>}]] [ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC] [{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]

La combinacin externa puede ser diestra o siniestra, LEFT OUTER JOIN o RIGHT OUTER JOIN. Con LEFT OUTER JOIN obtenemos todos los registros de en la tabla que situemos a la izquierda de la clausula JOIN, mientras que con RIGHT OUTER JOIN obtenmos el efecto contrario. Como mejor se ve la combinacin externa es con un ejemplo.

SELECT tCoches.matricula, tMarcas.marca, tCoches.modelo,

tCoches.color, tCoches.numero_kilometros, tCoches.num_plazas FROM tCoches LEFT OUTER JOIN tMarcas ON tCoches.marca = tMarcas.codigo

Esta consulta devolver todos los registros de la tabla tCoches, independientemente de que tengan marca o no. En el caso de que el coche no tenga marca se devolver el valor null para los campos de la tabla tMarcas. Visualmente (la consulta devuelve los datos en azul) ...

El mismo ejemplo con RIGHT OUTER JOIN.

SELECT tCoches.matricula, tMarcas.marca, tCoches.modelo, tCoches.color, tCoches.numero_kilometros, tCoches.num_plazas FROM tCoches RIGHT OUTER JOIN tMarcas ON tCoches.marca = tMarcas.codigo

Esta consulta devolver los registros de la tabla tCoches que tengan marca relacionada y todos los registros de la tabla tMarcas, tengan algn registro en tCoches o no. Visualmente (la consulta devuelve los datos en azul) ...

[arriba]

Union La clusula UNION permite unir dos o ms conjuntos de resultados en uno detras del otro como si se tratase de una nica tabla. De este modo podemos obtener los registros de mas de una tabla "unidos". La sintaxis corresponde a la de varias SELECT unidas a travs de UNION, como se muestra a continuacin:

SELECT [ALL | DISTINCT ] <nombre_campo> [{,<nombre_campo>}] FROM <nombre_tabla> [{LEFT|RIGHT OUTER JOIN <nombre_tabla> ON <condicion_combinacion>}]

[WHERE <condicion> [{ AND|OR <condicion>}]] [GROUP BY <nombre_campo> [{,<nombre_campo >}]] [HAVING <condicion>[{ AND|OR <condicion>}]] { UNION [ALL | DISTINCT ] SELECT [ALL | DISTINCT ] <nombre_campo> [{,<nombre_campo>}] FROM <nombre_tabla> [{LEFT|RIGHT OUTER JOIN <nombre_tabla> ON <condicion_combinacion>}] [WHERE <condicion> [{ AND|OR <condicion>}]] [GROUP BY <nombre_campo> [{,<nombre_campo >}]] [HAVING <condicion>[{ AND|OR <condicion>}]] } [ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC] [{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]

Para utilizar la clausula UNION debemos cumplir una serie de normas. Las consultas a unir deben tener el mismo nmero campos, y adems los campos deben ser del mismo tipo. Slo puede haber una nica clausula ORDER BY al final de la sentencia SELECT.

El siguiente ejemplo muestra el uso de UNION

SELECT tCoches.matricula, tMarcas.marca, tCoches.modelo, tCoches.color, tCoches.numero_kilometros, tCoches.num_plazas FROM tCoches INNER JOIN tMarcas ON tCoches.marca = tMarcas.codigo UNION SELECT tMotos.matricula, tMarcas.marca, tMotos.modelo, tMotos.color, tMotos.numero_kilometros, 0 FROM tMotos INNER JOIN tMarcas ON tMotos.marca = tMarcas.codigo; Puede observarse el uso de la constante cero en la segunda lista de seleccin para hacer coincidir el nmero y tipo de campos que devuelve la consulta UNION.

Ejemplo #1: Supone que en una consulta necesitas obtener datos de un empleado y adems datos del departamento, veamos como se hace: /* PL-SQL Procedures en Oracle */ Select T_empleado.nombre, T_empleado.direccion, T_empleado.cargo, T_departamento.codigo_dep, T_departamento.nombre_dep From t_empleado

INNER JOIN t_departamento ON t_empleado.id_departamento = t_departamento.id_departamento Where t_empleado = pin_id_empleado; En este ejemplo de PL-SQL Procedures en Oracle se esta uniendo la tabla t_empleado con la tabla t_departamento por su campo comn id_departamento utilizando la clusula INNER JOIN. Ejemplo #2: Veamos ahora como se hace la misma consulta anterior pero utilizando el signo igual en la clusula WHERE: /* PL-SQL Procedures en Oracle */ Select emp.nombre, emp.direccion, emp.cargo, dep.codigo_dep, dep.nombre_dep From t_empleado emp, t_departamento dep Where emp.t_empleado = pin_id_empleado And dep.id_departamento = emp.id_departamento; En este ejemplo se reemplaza la clusula INNER JOIN por una condicin dentro de la clusula WHERE en tus PL-SQL Procedures en Oracle, donde se une la tabla t_empleado (emp.id_departamento) con la tabla t_departamento (dep.id_departamento) solo usando el signo igual (=). Este ltimo ejemplo es el mtodo mas utilizado por los desarrolladores en la construccin de los PL-SQL Procedures en Oracle, ya que permite una rpida implementacin quedando un cdigo ms entendible a diferencia de utilizar la clusula INNER JOIN que es ms larga y engorrosa de aplicar. Te propongo que pruebes de inmediato estos ejemplos en tu Base de Datos con tus propias tablas, PL-SQL Procedures en Oracle y PL-SQL Function en Oracle, para que comiences a ejercitar la mano y aprendas a dominar esta nueva tcnica en tus PL-SQL Packages en Oracle. Estoy muy interesado en conocer tu opinin y/o comentario sobre este artculo, tambin cuntame sobre qu es lo que quieres saber de PL-SQL Procedures en Oracle y/o dime cul es tu principal frustracin a la hora de trabajar con PL-SQL Procedures en Oracle. Estar muy atento respondiendo tus preguntas y/o comentarios, gracias.

Reunin (join)
Contenidos 1. 1 Tipos de reunin 1. 1.1 Equijoin 2. 1.2 Self join 3. 1.3 Producto cartesiano 4. 1.4 Inner join, simple join 5. 1.5 Outer join 6. 1.6 Antijoin 7. 1.7 Semijoin 2 Outer join

2.

El uso de varias tablas en una consulta, y su concatenacin siguiendo cualquier criterio, se conoce habitualmente como join, el trmino en ingls adoptado y utilizado. Estamos hablando, por ejemplo, de: select * from asignaturas, profesores, imparte where profesores.dni = imparte.dni and asignatura = codigo

Tipos de reunin
Dependiendo de qu tablas se especifiquen en el from y del tipo de condicin exigida para relacionar las filas de esas tablas, el join recibe distintos nombres (terminologa que se puede considerar estndar):

Equijoin
Consultas que conllevan el uso de igualdades para la concatenacin de filas de varias tablas. El ejemplo anterior es una equijoin.

Self join
Estas consultas concatenan una tabla consigo misma: select i1.dni, ' imparte la misma asignatura que ', i2.dni from imparte i1, imparte i2 where i1.asignatura= i2.asignatura

dni

imparte la misma asignatura que

dni 21111222 21111222 21333444

21111222 imparte la misma asignatura que 21111222 imparte la misma asignatura que 21333444 imparte la misma asignatura que

Producto cartesiano
El producto cartesiano utiliza dos tablas sin la condicin de concatenacin del where: select dni, codigo from profesores, asignaturas

dni

codigo

21111222 DGBD 21222333 DGBD 21333444 DGBD 21111222 FBD 21222333 FBD 21333444 FBD 21111222 FP 21222333 FP 21333444 FP 21111222 HI 21222333 HI 21333444 HI 21111222 PC 21222333 PC 21333444 PC

Inner join, simple join


Realmente, se trata de la consulta habitual en SQL. Sin embargo, existe una sintaxis particular alternativa usando inner join: select nombre, descripcion from asignaturas join imparte on (codigo=asignatura) join profesores on (imparte.dni=profesores.dni)
nombre EVA GOMEZ EVA GOMEZ descripcion DISEO Y GESTION DE BASES DE DATOS FUNDAMENTOS DE LAS BASES DE DATOS

RAFAEL ROMERO PROGRAMACION CONCURRENTE

El resultado ser la concatenacin de todas aquellas filas, y nicamente esas, que cumplen la condicin que las relaciona. Es una construccin alternativa a la que hemos venido utilizando hasta ahora que nos debe ser familiar: select nombre, descripcion from asignaturas, profesores, imparte where profesores.dni = imparte.dni and asignatura = codigo Si acaso, puede tener cierta utilidad para no olvidarnos de enlazar cada par de tablas y dejar el where para otro tipo de condiciones: select nombre, descripcion from asignaturas join imparte on (codigo=asignatura) join profesores on (imparte.dni=profesores.dni) where descripcion NOT LIKE 'PROGRAMACION%'
nombre descripcion EVA GOMEZ DISEO Y GESTION DE BASES DE DATOS EVA GOMEZ FUNDAMENTOS DE LAS BASES DE DATOS

Outer join
El outer join se diferencia del inner join en que las filas de una tabla que se muestran en el resultado no necesariamente tienen su correspondiente fila o filas en la otra tabla. Por ejemplo, podramos querer obtener todos los profesores y, si da alguna asignatura, el cdigo de esas asignatura: select p.*, i.asignatura from profesores p left join imparte i on (p.dni=i.dni);

dni

nombre

categoria TEU TEU ASO6

ingreso

asignatura

21111222 EVA GOMEZ 21111222 EVA GOMEZ 21333444 RAFAEL ROMERO

1993-10-01 DGBD 1993-10-01 FBD 1989-06-16 1992-06-16 PC

21222333 MANUEL PALOMAR TEU

Ms adelante se profundiza en el outer join.

Antijoin
Estas consultas son las que utilizan el NOT IN para obtener aquellas filas de una tabla que no se relacionan con las de otra: select * from profesores

where dni not in (select dni from imparte);

dni

nombre

categoria

ingreso 1989-06-16

21222333 MANUEL PALOMAR TEU

Semijoin
Un semijoin devuelve filas que hacen cierta una subconsulta de un operador EXISTS sin duplicar filas. select * from profesores p where exists (select * from imparte i where i.dni = p.dni);

dni

nombre

categoria TEU

ingreso 1993-10-01 1992-06-16

21111222 EVA GOMEZ

21333444 RAFAEL ROMERO ASO6

El operador exists y este tipo de subconsultas se vern en sesiones ms avanzadas.

Dmonos cuenta que, prcticamente, lo nico que hemos hecho es dar nombre a los distintos tipos de consultas, algunas ya utilizadas durante el curso. No es importante ese nombre sino entender las necesidades de cada consulta y cmo satisfacerla. S es nueva, para este curso, la sintaxis del inner y el outer join. El primero, no hace falta desarrollarlo ms, el segundo s lo tratamos en la siguiente seccin. Tngase en cuenta, tambin, que ste no es un curso exhaustivo de SQL. Hay detalles de rendimiento que favorecen el uso de unos u otros tipos de consultas y, por supuesto, muchas ms opciones a la hora de incrementar ese rendimiento sobre todo en entornos de medianas o grandes bases de datos. Para ms informacin, podis consultar Oracle Database SQL Reference 10g Release 2 (10.2), que ha sido la fuente de esta sesin.

Outer join
Como ya hemos dicho, el outer join extiende el resultado de una consulta simple de, por ejemplo, dos tablas, obteniendo todas las filas que cumplen la condicin de concatenacin y, adems, todas o algunas de las filas de una tabla que no cumplen tal condicin. Supongamos dos tablas A y B: select * from A left [outer] join B on (condicin) Obtiene todas las filas relacionadas de A y B, y todas las no relacionadas de A. select * from A right [outer] join B on (condicin) Obtiene todas las filas relacionadas de A y B, y todas las no relacionadas de B. select * from A full [outer] join B on (condicin) (No soportado por MySQL) Obtiene todas las filas relacionadas de A y B, y todas las no relacionadas de A y B.

BD Ejemplo

PROFESORES ( dni varchar2(10), nombre varchar(40), categoria char(4), ingreso date ) CP (dni) ASIGNATURAS ( codigo char(5), descripcion varchar(35), creditos decimal(3,1), creditosp decimal(3,1) ) CP (cdigo) IMPARTE ( dni varchar(10), asignatura char(5) ) CP (dni, asignatura) CAj (dni) PROFESORES CAj (asignatura) ASIGNATURAS COORDINADORES ( dni varchar(10), nombre varchar(40), dpto char(4), asig char(5) ) CP (dni) CAj (asig) ASIGNATURAS

Para ver mejor el funcionamiento de las distintas alternativas de join, vamos a trabajar con una tabla adicional, COORDINADORES, en nuestra base de datos Ejemplo.

Muestra todos los coordinadores y, si lo hacen, las asignaturas que coordinan. select * from coordinadores left join asignaturas on (codigo=asig);

dni

nombre

dpto

asig FP HI

codigo FP HI

descripcion HISTORIA DE LA INFORMATICA

creditos 4.5

creditosp 4.5

55777666 AGAPITO CIFUENTES DLSI 66555444 ROMUALDO GOMEZ DLSI 99222111 CATURLO PEREZ DLSI

FUNDAMENTOS DE LA PROGRAMACION 9.0

Muestra los coordinadores que tienen asignatura y todas las asignaturas. select * from coordinadores right join asignaturas on (codigo=asig);

dni

nombre

dpto

asig

codigo DGBD FBD

descripcion

creditos

creditosp 3.0 1.5 4.5 1.5

DISEO Y GESTION DE BASES DE DATOS 6.0 FUNDAMENTOS DE LAS BASES DE DATOS 6.0 FUNDAMENTOS DE LA PROGRAMACION HISTORIA DE LA INFORMATICA PROGRAMACION CONCURRENTE 9.0 4.5 6.0

55777666 AGAPITO CIFUENTES DLSI 66555444 ROMUALDO GOMEZ DLSI

FP HI

FP HI PC

Muestra todos los coordinadores y todas las asignaturas y si hay relacin entre ellos. select * from coordinadores full join asignaturas on (codigo=asig); Lo que se espera de un full join es que aparezcan todos los datos de una y otra tabla, estn o no relacionados, ms o menos, lo que se muestra a continuacin:

dni

nombre

dpto

asig FP HI

codigo DGBD FP HI FBD PC

descripcion FUNDAMENTOS DE LA PROGRAMACION HISTORIA DE LA INFORMATICA PROGRAMACION CONCURRENTE

creditos 9.0 4.5

creditosp 3.0 4.5 1.5 1.5

DISEO Y GESTION DE BASES DE DATOS 6.0

55777666 AGAPITO CIFUENTES DLSI 66555444 ROMUALDO GOMEZ DLSI

FUNDAMENTOS DE LAS BASES DE DATOS 6.0 6.0

99222111 CATURLO PEREZ

DLSI

Sin embargo, full join no est soportado por MySQL aunque s por otros motores (Oracle PL/SQL) y si ejecutramos la sentencia

anterior el resultado es idntico a un join simple.

dni

nombre

dpto

asig FP HI

codigo FP HI

descripcion HISTORIA DE LA INFORMATICA

creditos 4.5

creditosp 4.5

55777666 AGAPITO CIFUENTES DLSI 66555444 ROMUALDO GOMEZ DLSI

FUNDAMENTOS DE LA PROGRAMACION 9.0

Potrebbero piacerti anche