 |
|
 |
Consultas combinadas. JOINS
Consultas combinadas.
Habitualmente cuando necesitamos recuperar la información de una base de datos nos encontramos con que dicha información se encuentra repartida en varias tablas, referenciadas a través de varios códigos. De este modo si tuvieramos una tabla de ventas con un campo cliente, dicho campo contendría el código del cliente de la tabla de cliente.
Sin embargo está forma de almacenar la información no resulta muy util a la hora de consultar los datos. SQL nos proporciona una forma facil de mostrar la información repartida en varias tablas, las consultas combinadas o JOINS.
Las consultas combinadas pueden ser de tres tipos:
-
Combinación interna
-
Combinación externa
-
Uniones
Combinación interna.
La combinación interna nos permite mostrar los datos de dos o más tablas a través de una condición WHERE.
Si recordamos los ejemplos de los capitulos anteriores tenemos una tabla de coches, en la que tenemos referenciada la marca a través del código de marca. Para realizar la consulta combinada entre estas dos tablas debemos escribir una consulta SELECT en cuya claúsula FROM escribiremos el nombre de las dos tablas, separados por comas, y una condición WHERE que obligue a que el código de marca de la tabla de coches sea igual al código de la tabla de marcas.
Lo más 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 código de la marca, o el campo marca de la tabla tMarcas, que contiene el nombre de la marca.
Otra opción es utilizar la cláusula INNER JOIN. Su sintaxis es identica a la de una consulta SELECT habitual, con la particularidad de que én la cláusula FROM sólo aparece una tabla o vista, añadiendose el resto de tablas a través de cláusulas 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 cláusula INNER JOIN permite separar completamente las condiciones de combinación 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 cláusula INNER JOIN, la razón 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 cláusula INNER JOIN.
Combinación Externa
La combinación interna es excluyente. Esto quiere decir que si un registro no cumple la condición de combinación 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.
Según 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 disposición la combinación externa. La combinación externa no es excluyente.
La sintaxis es muy parecida a la combinación 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 combinación 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 combinación 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 algún registro en tCoches o no.
Visualmente (la consulta devuelve los datos en azul) ...

Union
La cláusula UNION permite unir dos o más 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 través de UNION, como se muestra a continuación:
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 número campos, y además los campos deben ser del mismo tipo.
-
Sólo 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 selección para hacer coincidir el número y tipo de campos que devuelve la consulta UNION.
|
|
| |
 |
y qué es más rápido
por
marisol
Respuesta recibida el [26/07/2007 01:21:26]
|
 |
Hola! Buenas explicaciones. Estoy haciendo un proyecto en el que es sumamnete importante el rendimiento. Si necesito combinar 3 tablas, qué tipo de consulta es más rápida? Gracias.
|
| |
 |
Observacion union
por
CarlosHV
Respuesta recibida el [03/09/2007 04:10:07]
|
 |
en el union del ejemplo final, segundo select dice FROM tCoches, no seria mas bien tMotos?
Saludos, muy bueno el tutorial, lo estoy siguiendo de a pocos
|
| |
 |
Gracias CarlosHV, visto y corr...
por
Devjoker
Respuesta recibida el [04/09/2007 04:56:16]
|
 |
Gracias CarlosHV, visto y corregido.
|
| |
 |
Excelente,
por
Manuel R. Bercian
Respuesta recibida el [05/09/2007 08:21:54]
|
 |
Sigue adelante, Excelente curso
|
| |
 |
Ayudame!!
por
CarlosHV
Respuesta recibida el [12/09/2007 01:11:12]
|
 |
Hola CarlosHv veo q ya tienes conocimientos intermedios espero me puedas orientar apenas inicio en esto te dejo mi correo: alan_pr_18@hotmail.com espero me agregues y podamos intercambiar conocimientos
|
| |
 |
ayudame
por
alan
Respuesta recibida el [12/09/2007 01:11:48]
|
 |
Hola CarlosHv veo q ya tienes conocimientos intermedios espero me puedas orientar apenas inicio en esto te dejo mi correo: alan_pr_18@hotmail.com espero me agregues y podamos intercambiar conocimientos
|
| |
 |
buenos
por
karolina
Respuesta recibida el [15/09/2007 02:25:33]
|
 |
hola .. es muy bueno esta bien explicado kisiera saber si sql2005 es igual a oracle
|
| |
 |
GRACIAS
por
LUIS mENDOZA
Respuesta recibida el [15/01/2008 03:51:06]
|
 |
MUCHISIMAS GRACIAS, MUY BUENOS LOS EJEMPLOS EXPUESTOS, ME FUERON MUY UTILES
|
| |
 |
QUISIERA CONOCER MAS
por
ALFONSO
Respuesta recibida el [24/02/2008 07:30:03]
|
 |
QUE MANUAL ME RECOMIENDAN PARA CONOCER MAS SOBRE SQL SERVER 2005 YA QUE ESTOY EMPEZANDO DE DBA Y LA VERDAD QUISIERA SABER MAS PARA TENER MAS CONFIANZA apg_29@hotmail.com
GRACIAS
|
| |
 |
Que pasa aqui?
por
Gustavo
Respuesta recibida el [15/05/2008 09:57:33]
|
 |
SELECT prh.segment1 NUM_REQ ,prl.item_description descripcion ,prd.requisition_line_id -- TEMPORAL ,pd.req_distribution_id -- TEMPORAL FROM po_requisition_headers_all prh RIGHT OUTER JOIN po_requisition_lines_all prl ON prh.requisition_header_id = prl.requisition_header_id RIGHT OUTER JOIN po_req_distributions_all prd ON prl.requisition_line_id = prd.requisition_line_id RIGHT OUTER JOIN po_distributions_all pd ON prd.distribution_id = pd.req_distribution_id WHERE TRUNC(prh.creation_date) >= :fecha_ini AND TRUNC(prh.creation_date) <= :fecha_fin AND prh.segment1 >= nvl(:P_REQ_INI,prh.segment1) --RANGO DE LA REQUISICION AND prh.segment1 <= nvl(:P_REQ_FIN,prh.segment1) --RANGO DE LA REQUISICION
en la consulta anterior, la tabla pd ya no trae registro coincidenete y a pesar de ser un outer (incluyente) no muestra el registro, tal vez mi sintaxis este mal, espero que alguien pueda darme un tip.
|
| |
 |
visa unsecured
por
Laos
Respuesta recibida el [17/08/2008 04:28:52]
|
 |
Very Nice Site! Thanx! http://excellent-credit-card.blogspot.com
|
| |
 |
Como seria esta?
por
germ8n
Respuesta recibida el [23/09/2008 02:40:49]
|
 |
Lo que tengo que hacer es esto: Mostrar la nota del periodo "marzo/abril" de la materia "base de datos" de todos los alumnos del grupo "3Iz", ordenando la consulta por periodo y por materia.
Las tablas son estas: Rendimientos(Numero, grupo, codmateria, periodo, nota)
Materias(codmateria, Nombre)
alumnos(numero,grupo, ci, nombre, apellido, fecha_nac)
Por favor es urgente para mañana. gracias
|
| |
 |
que mier...
por
cristian daiel
Respuesta recibida el [26/09/2008 04:10:18]
|
 |
esto pa que sirve no ehhh que perez...
|
| |
 |
OsKr Es GaY
por
Ronald..
Respuesta recibida el [26/09/2008 04:16:36]
|
 |
oskr lloreda es gay y tengo fotos juaz juaz q pereza la programacion bfffff
|
| |
 |
jejejejejejejeje locu pátron
por
danichitu
Respuesta recibida el [26/09/2008 04:17:42]
|
 |
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj chat esta como leeeeeeeeeeeeeeeeeeeeeeeeeeeentoooooooooooo jijiijiji oooOOOooopPPPPppSSSSSsssssSSSS.....XD
|
| |
 |
sql???????????''''
por
danichitu
Respuesta recibida el [26/09/2008 04:20:38]
|
 |
donDe estA sQl No lo veO Ese mAN MantieNe perdIDO jIjIjIjIjIJijijjii
me Lo Sludan sI Lo ven
|
| |
 |
NECESITO DEDO
por
oscar d'gay
Respuesta recibida el [26/09/2008 04:21:11]
|
 |
QUIEN ME PUEDE DECIR COMO HACER UN DEDO POR CODIGO SQL???
|
| |
 |
Esto está excelente
por
Edu 2008
Respuesta recibida el [24/10/2008 05:01:10]
|
 |
La verdad que es la primera vez que veo una teoria completa del funcionamiento de JOINS, porque por otros lados esto nunca se llega a entender del todo bien y por eso que no se utiliza adecuadamente.
|
| |
 |
para Edu 2008
por
Mr.X
Respuesta recibida el [03/11/2008 08:14:44]
|
 |
Te pasas de lanza, como eres huvon para investigar las combinaciones, yo las aprendi solo sin tutoriales, este tutorial es efectivo para la memoria, pero la inteligencia es otra cosa.........
|
| |
 |
esta muy bueno, se agradece.
...
por
Anónimo
Respuesta recibida el [09/11/2008 03:25:44]
|
 |
esta muy bueno, se agradece.
saludos
|
| |
 |
Muchas gracias...
por
Anónimo
Respuesta recibida el [04/01/2009 12:13:51]
|
 |
Muchas gracias
|
| |
 |
Gracias
por
Luis Diego - Costa Rica
Respuesta recibida el [07/01/2009 12:28:19]
|
 |
El material esta muy bien preparado, esta con fundamento y muy util. Muchas gracias !
|
| Añadir comentario ... |
Para preguntar utiliza los foros
|
|

|
Consultas combinadas. JOINS |
|
Autor:
Pedro Herrarte Sánchez
|
|
Visitas:
69121 |
Fecha de publicación:
22/10/2005 |
Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación.
Posee mas de diez años de experiencia trabajando para las principales empresas de España.
Es especialista en tecnologías .NET, entornos Web, bases de datos (SQL Server y ORACLE) e integración de sistemas.
Es experto en desarrollo (C#, ASP.NET, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE).
Es fundador, diseñador y programador de www.devjoker.com. |
|
|
Visitas:
40
|
Comentarios:
0
|
Archivo:
Articulos
|
|
Visitas:
109
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
155
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
33
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
285
|
Comentarios:
1
|
Archivo:
Articulos
|
Visitas:
841
|
Comentarios:
2
|
Archivo:
Articulos
|
Visitas:
712
|
Comentarios:
1
|
Archivo:
Articulos
|
Visitas:
449
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
1053
|
Comentarios:
1
|
Archivo:
Articulos
|
Visitas:
250
|
Comentarios:
0
|
Archivo:
Articulos
|
|
|
|
 |
| Encuesta |
|
¿A que perfil te adaptas mejor? |
|
|
|
|
|
|
|
|
 |