Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=578062e0-70b2-40ab-b047-815e05ff4eb7

Fundamentos de SQL: Consultas SELECT multi-tabla - JOIN

SQL-Consultas-Multi-Tabla

Continuando con nuestro camino para dominar los fundamentos de SQL, en un anterior post vimos lo básico de crear consultas con la instrucción SELECT. A continuación vamos a complicar un poco la cosa aprendiendo a realizar consultas en varias tablas de la base de datos al mismo tiempo.

Es habitual que queramos acceder a datos que se encuentran en más de una tabla y mostrar información mezclada de todas ellas como resultado de una consulta. Para ello tendremos que hacer combinaciones de columnas de tablas diferentes.

En SQL es posible hacer esto especificando más de una tabla en la cláusula FROM de la instrucción SELECT.

Tenemos varias formas de obtener esta información.

Una de ellas consiste en crear combinaciones que permiten mostrar columnas de diferentes tablas como si fuese una sola tabla, haciendo coincidir los valores de las columnas relacionadas.

Este último punto es muy importante, ya que si seleccionamos varias tablas y no hacemos coincidir los valores de las columnas relacionadas, obtendremos una gran duplicidad de filas, realizándose el producto cartesiano entre las filas de las diferentes tablas seleccionadas.

Vamos a ver este importante detalle con un ejemplo simple. Consideremos estas tres consultas sobre la base de datos Northwind:

SELECT COUNT(*) FROM Customers
SELECT COUNT(*) FROM Orders
SELECT COUNT(*) FROM Customers, Orders

La primera instrucción devuelve 91 filas (los 91 clientes), la segunda 830 filas (los pedidos), y la tercera 75.530 (que son 830 x 91, es decir, la combinación de todas las filas de clientes y de pedidos).

La otra manera de mostrar información de varias tablas -mucho más habitual y lógica- es uniendo filas de ambas, para ello es necesario que las columnas que se van a unir entre las dos tablas sean las mismas y contengan los mismos tipos de datos, es decir, mediante una clave externa.

Operaciones de unión - JOIN

La operación JOIN o combinación permite mostrar columnas de varias tablas como si se tratase de una sola tabla, combinando entre sí los registros relacionados usando para ello claves externas.

Las tablas relacionadas se especifican en la cláusula FROM, y además hay que hacer coincidir los valores que relacionan las columnas de las tablas.

Veamos un ejemplo, que selecciona el número de venta, el código y nombre del cliente y la fecha de venta en la base de datos Northwind:

SELECT OrderID, C.CustomerID, CompanyName, OrderDate
FROM Customers C, Orders O
WHERE C.CustomerID = O.CustomerID

Para evitar que se produzca como resultado el producto cartesiano entre las dos tablas, expresamos el vínculo que se establece entre las dos tablas en la cláusula WHERE. En este caso relacionamos ambas tablas mediante el identificador del cliente, clave existente en ambas. Fíjate en como le hemos otorgado un alias a cada tabla (C y O respectivamente) para no tener que escribir su nombre completo cada vez que necesitamos usarlas.

Hay que tener en cuenta que si el nombre de una columna existe en más de una de las tablas indicadas en la cláusula FROM, hay que poner, obligatoriamente, el nombre o alias de la tabla de la que queremos obtener dicho valor. En caso contrario nos dará un error de ejecución, indicando que hay un nombre ambiguo.

Hay otra forma adicional, que es más explícita y clara a la hora de realizar este tipo de combinaciones -y que se incorpora a partir de ANSI SQL-92- que permite utilizar una nueva cláusula llamada JOIN en la cláusula FROM, cuya sintaxis es el siguiente:En el caso del ejemplo anterior quedaría de la siguiente forma:

SELECT [ ALL / DISTINC ] [ * ] / [ListaColumnas_Expresiones]
FROM NombreTabla1 JOIN NombreTabla2 ON Condiciones_Vinculos_Tablas

De esta manera relacionamos de manera explícita ambas tablas sin necesidad de involucrar la clave externa en las condiciones del SELECT (o sea, en el WHERE). Es una manera más clara y limpia de llevar a cabo la relación.

Esto se puede ir aplicando a cuantas tablas necesitemos combinar en nuestras consultas. Veamos un ejemplo en ambos formatos que involucra más tablas, en este caso las tablas de empleados, clientes y ventas:

SELECT OrderID, C.CustomerID, CompanyName, OrderDate
FROM Customers C, Orders O, Employees E
WHERE C.CustomerID = O.CustomerID AND O.EmployeeID = E.EmployeeID

El segundo formato permite distinguir las condiciones que utilizamos para combinar las tablas y evitar el producto cartesiano, de las condiciones de filtro que tengamos que establecer.

Veamos un ejemplo como el anterior, pero ahora además necesitamos que el cliente sea de España o el vendedor sea el número 5.

En el primer formato tendríamos algo como esto:

SELECT OrderID, C.CustomerID, CompanyName, OrderDate
FROM Customers C, Orders O, Employees E
WHERE (C.CustomerID = O.CustomerID AND O.EmployeeID = E.EmployeeID)
AND (C.Country = 'Spain' OR E.EmployeeID = 5)

Es decir, estamos mezclando en el WHERE las uniones de tablas, y las condiciones concretas de filtro de la consulta, quedando todo mucho más liado.

Sin embargo usando el segundo formato con JOIN, la consulta es mucho más clara:

SELECT OrderID, C.CustomerID, CompanyName, OrderDate
FROM Customers C JOIN Orders O ON C.CustomerID = O.CustomerID JOIN Employees E ON O.EmployeeID = E.EmployeeID
WHERE C.Country = 'Spain' OR E.EmployeeID = 5

Aquí se aprecia claramente que la utilización de JOIN simplifica la lectura y comprensión de la instrucción SQL, ya que no necesita el uso de paréntesis y tiene una condición WHERE más sencilla.

También podemos utilizar una misma tabla con dos alias diferentes para distinguirlas. Veamos un ejemplo, supongamos que tenemos una columna sueldo en la tabla de empleados, y queremos saber los empleados que tienen un sueldo superior al del empleado 5:

SELECT E1.EmployeeID
FROM Employees E1 JOIN Employees E2 ON E1.Sueldo > E2.Sueldo
WHERE E2.EmployeeID = 5

Con esto hemos aprendido lo básico de trabajar con varias tablas y generar combinaciones de datos entre éstas.

En un próximo artículo aprenderemos a ver los otros dos tipos de combinaciones que existen: las combinaciones internas y las externas, así como las combinaciones de conjuntos de resultados (uniones, intersecciones, etc...).

Fecha de publicación:
campusMVP campusMVP es la mejor forma de aprender a programar online y en español. En nuestros cursos solamente encontrarás contenidos propios de alta calidad (teoría+vídeos+prácticas) creados y tutelados por los principales expertos del sector. Nosotros vamos mucho más allá de una simple colección de vídeos colgados en Internet porque nuestro principal objetivo es que tú aprendas. Ver todos los posts de campusMVP
Archivado en: Acceso a Datos

¿Te ha gustado este post?
Pues espera a ver nuestra newsletter...

Suscríbete a la newsletter

La mejor formación online para desarrolladores como tú

Comentarios (16) -

Muy completa la información. Muchas gracias.

Por favor, me gustaría saber como hacer un 'SELECT  *' que incluye varias tablas. Existen un mismo nombre de campo por ejemplo 'codigo'  que se encuentra en todas las tablas (No es el 'id'). Pero cuando ejecuto el query, este campo asume el mismo valor del último registro. Me gustaría que al hacer el query, cada nombre de campo apareciera con el nombre de la tabla incluido para que se diferenciaran entre si. Por ejemplo: Antes: codigo=>101, codigo=101.
Después: tabla1.codigo=101, tabla2.codigo=202. Gracias.

Juan Bolivar
Colombia Juan Bolivar

Sugieron que le pongas un alias a cada uno de los atributos que quieres diferenciar. Te lo resumo en una sentencia:
SELECT Tabla1.codigo AS [Nombre del alias], Tabla2.codigo AS [Nombre del alias] FROM Tabla1, Tabla2

tania nallely zuno morales
tania nallely zuno morales

podrias ponerle un  alias a cada uno de los atributos que quieres diferenciar. por ejemplo
SELECT Tabla1.codigo AS [Nombre del alias], Tabla2.codigo AS [Nombre del alias] FROM Tabla1, Tabla2, no se si es esa la respuesta que buscas

De donde sale el igual? o mas bien como se diria para una expocision que de donde saldria el igual?

Hola. Muy bueno el manual. Quise poner en práctica lo del último ejemplo, uso SQLServer2014, y no funciona. Pone que EmployeesID, el que está seguido del SELECT, es un nombre de columna ambiguo, por lo cual no se ejecuta. ¿Por qué?
Por otro lado no entiendo si el 'JOIN' y 'ON' son los mismo que 'WHERE' y '='. Siendo así por qué habría de usar JOIN. Eso es lo que no me queda claro, no hay una explicación del por qué usar JOIN, sino que dice que queda más claro. Gracias. Saludos!

Martin Andres Gutierrez Lopez
Martin Andres Gutierrez Lopez

El JOIN es mas claro porque separa las clausulas de UNION de TABLAS de las de filtro de datos.
Antes de SQL-92, todo se ponia en el WHERE, lo cual se entendía bien, pero tenias que tener cuidado con tantos parentesis.
con la revision SQL-92 en el WHERE solo van los filtros de datos, mientras que para la union de tablas se usa el JOIN y el ON.

Hola de nuevo. Acabo de modificar y colocando SELECT E1.EmpleyeeID funciona. Pero sigo sin entender en qué cambia de usar WHERE a JOIN mas que la simplificación y comprensión de la query. Gracias. Saludos.

campusMVP
campusMVP

Hola Emiliano:

Efectivamente le faltaba indicar con mayor precisión en el "SELECT" el campo exacto que quieres traer ya que el procesador de SQL no sabe que estás cruzando la tabla consigo misma y por lo tanto ve dos campos en los resultados con el mismo nombre (EmployeeID) y no sabe a cuál de los dos te refieres. En este caso son idénticos, así que basta con poner delante el nombre de la tabla "E1.EmployeeID" o "E2.EmployeeID" valdrían.

En cuanto a ¿por qué usar JOIN en lugar de un WHERE y una subconsulta?
Bueno, en este artículo se estaba explicando el uso de JOIN así que el ejemplo se ha puesto principalmente por eso y para demostrar que se puede hacer un JOIN con una misma tabla, no solo con tablas diferentes. Aparte de eso la consulta mostrada y esta:

SELECT EmployeeID FROM Employees
WHERE Sueldo > (SELECT Sueldo FROM Employees WHERE EmployeeID = 5)

son equivalentes y de hecho incluso su plan de ejecución es el mismo.

Lo de la simplificación y claridad de comprensión de la consulta es importante, pero en este caso a alguna gente le costará más entender la que usa JOIN que la segunda opción o al revés. Es una cuestión de gustos.

Saludos.

hola, muy bueno el tutorial, estoy realizando unas pruebas con multiples tablas, son 7 y tengo algunos problemas, quisiera saber si podia contar con tu ayuda para resolverlo, como podria pasarte las tablas y sus estructuras. Gracias.

Jose Luis
Jose Luis

Estimados una consulta:

Saben de algún query para contar el numero total de tablas no relacionadas y las que están libres de una BD?

me gusta el pico

HOLA, QUISIERA SABER COMO PODRÍA CONSOLIDAR VARIAS TABLAS EN UNA YA QUE ACTUALMENTE NO HE PODIDO. LAS TABLAS ESTAN CON NOMBRE POR AÑO Y MES (FROM p_recepcion201307 luego sigue la p_recepcion201308, p_recepcion201309.....hasta p_recepcion201707) y aun no he podido juntar la informacion de estas tablas en una sola, por favor apoyenme.

Nota: dejo el código abajo.

SELECT        TOP (5000) rec_iid, rec_iidcuenta, rec_calarma, rec_czona, rec_iusuario, rec_tfechahora, rec_nestado, rec_cContenido, rec_tFechaProceso, rec_ioperador, rec_cObservaciones, rec_cTerminal, rec_idResolucion,
                         rec_idReceptor, rec_cCategorizacion, rec_iNYR, rec_iTE, rec_tFechaRecepcion, rec_nOrigen, rec_idMap, rec_idFwd, rec_iMinutosEspera, rec_iPuerto, rec_idLoc, rec_iPrioridad, usuario_iCodigo,
                         usuario_cNombre, zonas_cCodigo, zonas_cDescripcion, _Origen, _Puerto
FROM            p_recepcion201312
WHERE        (rec_iidcuenta = '15')

MARTIN GUTIERREZ
MARTIN GUTIERREZ

Hola Joe, se sobreentiende que las tablas p_recepcionYYYYMM son tablas historicas y que tienen la misma estructura todas las tablas con los mismos campos.
Solo debes hacer un UNION al SELECT que ya pusiste para una tabla.
Por ejemplo, si quieres unir 5 tablas de 5 meses, haces
SELECT .... FROM p_recepcion201307 UNION
SELECT .... FROM p_recepcion201308 UNION
SELECT .... FROM p_recepcion201309 UNION
SELECT .... FROM p_recepcion201310 UNION
SELECT .... FROM p_recepcion201311

Luego al resultante, le puedes hacer un SELECT de consolidación si quieres sacar promedios, sumatorias por meses, etc.

hola necesito ayuda para una busqueda explico tengo un formulario con un boton buscar y cuadro de texto.  quiero que me muestre al hacer la busqueda por Usuario los datos de ese usuario.
esta es mi tabla:
codigo
usuario
nombre
apellido
departamento
sucursal
windows
licencia
descripcion

cuadro de texto: Texto124, la etiqueta usuario: Etiqueta125 y el boton de busqueda: Comando232
quiero que sea el evento al hacer clic en el boton buscar

Alguien me podria ayudar por favor

Alex Vargas
Alex Vargas

Buenísima la información, me ha ayudado muchísimo en la comprensión del funcionamiento de los JOINS.

Pingbacks and trackbacks (1)+

No se aceptan más comentarios