Explicación visual de los SQL Join - Unir tablas con SQL

12 de Octubre del 2007 Escrito por Alex Barros

Me ha parecido muy interesante el artículo escrito por Jeff Atwood titulado A Visual Explanation of SQL Joins.

Tanto es así que he decidido traducir este artículo al español. Disfrutad:

Autor Original: Jeff Atwood
Fecha: 11/10/07
Traductor: Alex Barros

Pensé que el post de Ligaya Turmelle sobre SQL joins era una genial introducción para los desarrolladores primerizos. Dado que los SQL joins están basados fundamentalmente en conjuntos relacionados, el uso de diagramas de Venn para explicarlo parece lo más acertado. De todas formas, igual que los comentaristas de su post, opino que sus diagramas de Venn no encajaban con la sintaxis de SQL join en mis pruebas.

Aún así me encanta el concepto, así que veamos si podemos hacerlo funcionar. Supongamos que tenemos las dos siguientes tablas. La tabla A está a la izquierda, y la tabla B está a la derecha. Las rellenaremos con cuatro registros cada una.

tabla A y B muestra

Ahora unamos estas dos tablas por el campo nombre de algunas formas distintas, y veamos si podemos obtener unas representaciones conceptuales con los ingeniosos diagramas de Venn.

Inner join sólo produce los registros que coinciden en las dos tablas A y B.

  1. SELECT * FROM TablaA
  2. INNER JOIN TablaB
  3. ON TablaA.nombre = TablaB.nombre

Resultado de Inner Join Join Inner

Full outer join produce el conjunto de todos los registros en las tablas A y B, con registros coincidentes en ambos lados cuando sea posible. Si no hay coincidencia, el lado que falta contendrá null.

  1. SELECT * FROM TablaA
  2. FULL OUTER JOIN TablaB
  3. ON TablaA.nombre = TablaB.nombre

Resultado de Full Outer Join Join Cartesian

Left outer join produce el conjunto completo de registros de la tabla A, con los registros coincidentes (si están disponibles) en la tabla B. Si no hay coincidencia, el lado derecho contendrá null.

  1. SELECT * FROM TablaA
  2. LEFT OUTER JOIN TablaB
  3. ON TablaA.nombre = TablaB.nombre

Resultado de Left Outer Join Join Left

Para producir el conjunto de registros en la tabla A, pero no en la tabla B, usamos el mismo Left Outer Join, y luego excluimos los registros que no queremos del lado derecho mediante una cláusula Where.

  1. SELECT * FROM TablaA
  2. LEFT OUTER JOIN TablaB
  3. ON TablaA.nombre = TablaB.nombre
  4. WHERE TablaB.id IS NULL

Resultado de Left Outer Join con exclusión Join Left Outer

Para producir el conjunto de registros únicos de la tabla A y la tabla B, usamos el mismo Full Outer Join, y luego excluimos los registros que no queremos de los dos lados mediante una cláusula Where.

  1. SELECT * FROM TablaA
  2. FULL OUTER JOIN TablaB
  3. ON TablaA.nombre = TablaB.nombre
  4. WHERE TablaA.id IS NULL
  5. OR TablaB.id IS NULL

Resultado de Full Outer Join con exclusión Join Outer

También hay un cross join, el cuál no puede ser expresado con un diagrama de Venn:

  1. SELECT * FROM TablaA
  2. CROSS JOIN TablaB

Esto une “todo con todo”, dando como resultado 4 x 4 = 16 filas, muchas más de las que teníamos en los conjuntos originales. Si haces unos simples cálculos, puedes ver por qué es un Join muy peligroso de ejecutar en tablas grandes.

Categorias: MySQL, Web |

Hay 35 comentarios, pero nos falta el tuyo

bendem Ha dicho:

Whow!! Muchas gracias… joder que sencillo que es verlo con estos gráficos de conjuntos.

Alex Barros Ha dicho:

Eso mismo pensé yo al leer el artículo original. No pude resistir la traducción, esto nadie debería perdérselo.

DbRunas - Explicacin visual de los SQL Join - Unir tablas con SQL Ha dicho:

[...] of SQL Joins. Tanto es as que he decidido traducir este artculo al espaol.Articulo completo: http://boozox.net/mysql/explicacion-visual-de-los-sql-join-unir-tablas-con-sql/ [...]

gafeman Ha dicho:

ojala hubiese tenido como tu y no uno que conozco jeje

Alex Barros Ha dicho:

Jeje, siempre viene bien una explicación detallada como esta.

A más de un profesor de mi universidad le pedía yo que hiciera cosas así…
Como dice un dicho español: Las cosas claras, y el chocolate espeso!

UnLugar » Blog Archive » SQL Join : entendiendo visualmente Ha dicho:

[...] Por aquí me encuentro con este post: Explicación visual de los SQL Join. [...]

PRINCIPAINTE Ha dicho:

CON ESTE ARTITUCULO SALI DE DUDAS SOBRE EL MANEJO DE JOIN, ESTA CLARISIMO OJALA HUBIERA MAS ARTICULOS ASI DE BIEN EXPLICADOS, IGUAL SI ME PUDIERAN AYUDAR CON SUM YA QUE LO HE INTENTADO PERO NO PUEDO REALIZAR UNA CONSULTA UTILIZANDO SUM Y JOIN
ESTE ES MI CODIGO, PERO CUANDO TRATO DE AGREGAR MAS CAMPOS PARA MOSTRAR ME MANDA ERROR

/*TRANSFORM Sum(T0.QUANTITY) AS ‘CANTIDAD’, SUM(T0.LINETOTAL)AS ‘TOTAL’*/select T0.BASECARD AS ‘CODIGO’, SUM ( T0.QUANTITY ) AS ‘CANTIDAD’, sum ( T0.LINETOTAL) AS ‘TOTAL’
from OINV T1 FULL OUTER JOIN INV1 T0 ON T0.basecard =T1.cardcode GROUP BY T0.basecard ORDER BY T0.basecard

Alex Barros Ha dicho:

Principiante, te agradecería que no escribas en mayúsculas, poque cuesta leer, y porque se considera gritar.

No domino demasiado el lenguaje SQL (este artículo es una traducción). Lo único que he notado extraño en tu código son las asignaciones. Cuando escribes Sum(T0.QUANTITY) AS ‘CANTIDAD’ asignas a CANTIDAD el resultado anterior, pero que yo recuerde no debe llevar comillas, cuando haces asignaciones.

El código te quedaría así:

SELECT T0.BASECARD AS CODIGO, SUM ( T0.QUANTITY ) AS CANTIDAD, sum ( T0.LINETOTAL) AS TOTAL
from OINV T1 FULL OUTER JOIN INV1 T0 ON T0.basecard =T1.cardcode GROUP BY T0.basecard ORDER BY T0.basecard

Contéstame si te ha funcionado o no.

maykol Ha dicho:

estoy usando la siguiente consulta de union y me da error de sintaxis en la clausula from

SELECT *FROM consultorio
INNER JOIN caminata 6 minutos ON consultorio.ecg_pdf = caminata 6 minutos.ecg_pdf

Alex Barros Ha dicho:

Separa el asterisco del from, eso lo primero.

Y en segundo lugar, no recomiendo que tengas una tabla cuyo nombre contiene espacios.

Aparte de esos dos apuntes, todo el resto es correcto, si existen las tablas “consultorio” y “caminata 6 minutos” y los campos “ecg_pdf” en las dos tablas.

VicHaunter Ha dicho:

Un premio a la sencillez. Me quito el sombrero, has resuelto todas mis dudas sobre su funcionamiento y mira que le he dado vueltas. Gracias y un saludo

Alex Barros Ha dicho:

Todo un placer. Me alegra que pueda servir. Es un recurso que no pude dejar de traducir, por su enorme claridad ante esta cuestión algo compleja.

Fabian Andres Ha dicho:

ESta muy interesante, te amo.

Nico Ha dicho:

Excelente artículo, muchas gracias por tu tiempo. Te hago una consulta: es posible hacer un Inner Join con 3 tablas? porque he probado diferentes sintaxis pero no encuentro una que resulte.
Una vez más, muchas gracias.

Jorge Troncoso Ha dicho:

Alex Barros, con una simple prueba podras darte cuenta que no es necesario separar el asterisco de la palabra FROM, eso no tiene nada que ver. De echo una consulta puede inclusive hacerse asi:

select*from tabla

…y funcionará.

Saludos.

Alex Barros Ha dicho:

Gracias por el apunte, Jorge. No conocía si funciona escribiendo todo junto, era más un tema de pulcritud en el código.

@nico: Realmente no lo se, y algunas personas me lo han preguntado. Investigaré al respecto.

MARINO MENDEZ Ha dicho:

eres el mejor del mundo, estoy a punto de ganarme 3,000 dolares gracias a ti, enviame un correo a ver si se te pega algo

paty Ha dicho:

hola que tal esta genial todo esto aunque tengo una preguntilla
cuando tengo dos tablas tabala a y tabla b solo quiero que salga una sola vez el campo con el que estan ligadas espero me entiendas y me ayudes gracias

Alex Barros Ha dicho:

@paty: debería saber un poco más el contexto en el que te encuentras. Estás en un script PHP? si deseas que te ayude, tendrás que proporcionar un poco más de información.

Sandro Ha dicho:

SELECT (campoligado) FROM TABLA A, TABLA B
WHERE A.campoligado = B.campoligado AND
A.campoligado = ?

Sandro Ha dicho:

Muy Agradecido por la Traduccion

Alex Barros Ha dicho:

No entiendo muy bien tu primer comentario, Sandro. Necesitas que te ayude con alguna sentencia SQL?

En ese caso te pido que me detalles cuál es el problema y me comentes un poco el contexto en el que te encuentras.

paty Ha dicho:

Muchas gracias Alex por todo y dejame decirte que estoy haciendo una aplicacion en netbenas osea con java y como manejador de base de datos en mysql

De un principio Piante Ha dicho:

Buenisima explicación, conceptual al maximo.
digno.

Alex

De un principio Piante Ha dicho:

Alex,

Mi viejo please,
Esta query de consistencia, funciona, pero, debido al universo (cantidad de registros) de algunas tablas, necesito sumar en esta misma query los que quedan con OK o con error, como lo hago?.Gracias.
Atte, Alex Quiroz.

select tabla1.campo1, tabla2.campo1,
(Case when tabla1.campo1 = tabla2.campo1 Then
‘OK’ Else ‘ERROR’
End)AS resp_create
FROM tabla1 INNER JOIN tabla2 tabla1.llave_tabla1=tabla2.llave_tabla2 Where tabla1.llave_tabla1 IS NOT Null
and IS NOT Null tabla2.llave_tabla2
Order by resp_create

luis alberto Ha dicho:

hola ojala me puedan ayudar, soy nuevo en esto del mysql, estoy realizando una base de datos con php quiero mostrar informacion de dos tablas que cree cliente y ciudad ellas tienen en comun el campo cod_ciudad, la idea es mostrar la informacion de la tabla ciudad tambien en el mismo reporte.
gracias de antemano

Alex Barros Ha dicho:

Una vez más me pedís ayuda muy general.

Luis: Busca tutoriales sobre lectura y muestra de tablas SQL, practica, después reúne información sobre la unión Inner Join en SQL (como este artículo), practica, haz prueba y error.

Es la única forma de enfrentarse a estas cosas.

Si tienes alguna duda concreta, entonces ya puedes contactar conmigo por mail, o mediante el blog. Pero dudas generales, son demasiado complejas de explicar.

Un saludo.

luis alberto Ha dicho:

Bueno gracias a tu consejo investige un poco mas acerca de consultas y logre mi objetivo que era mostrar la informacion de varias tablas en una sola consulta total no se si sea la mas idonea y asi quedo

SELECT * FROM CLIENTE,CIUDAD,ACTIVIDAD_ECONOMICA,DEPARTAMENTO WHERE (CLIENTE.cod_ciudad=CIUDAD.cod_ciudad)and(CLIENTE.cod_actividad=ACTIVIDAD_ECONOMICA.cod_actividad)and (CIUDAD.cod_depto=DEPARTAMENTO.cod_depto)and (CLIENTE.nom_cliente LIKE ‘%” . $_POST['txtbusqueda'] . “%’

como ves se torno algo extensa y compleja “por lo menos para mi” ahora mi inquietud es si hay forma de simplificar esta consulta, y ademas quiero hacer una busqueda multiple desde varios textbox, porque como ves en la parte final de la consulta involucro la busqueda desde un text identificado como txtbusqueda al campo nomcliente, ahora quiero buscar en 6 campos a la ves con valores introducidos en 6 textbox es posible esto?

Alex Barros Ha dicho:

La sentencia SQL no es demasiado extensa, al menos en comparación con muchas que he visto y con las que he trabajado. Por la extensión no te preocupes demasiado.

Si quieres buscar en 6 campos al mismo tiempo, puedes convertir el último parentesis en una serie de ORs que busquen en esos campos. Por ejemplo:

… and (CIUDAD.cod_depto=DEPARTAMENTO.cod_depto)and (CLIENTE.nom_cliente LIKE ‘%” . $_POST[’txtbusqueda’] . “%’ OR TABLA.campo LIKE ‘%” . $_POST[’txtbusqueda2’] . “%’ OR TABLA2.campo2 LIKE ‘%” . $_POST[’txtbusqueda3’] . “%’ …… etc)

luis alberto Ha dicho:

Gracias Alex por tu pronta respuesta, me ha sido de gran ayuda para entender mas acerca de las consultas en mysql, segui tu consejo al poner los or si dejo cualquiera de los 6 campos de busqueda vacio no filtra informacion me sigue mostrando todos los registros sin embargo si en vez de or pongo and filtra la busqueda por el criterio que ponga en el los texbox, aun la logica no la comprendo no tengo muy claro la diferencia entre un and y un or por lo que realize la consulta a prueba y error si me pudieras explicar la diferencia te agradeceria puede ser algo tonto pero es mejor pasar por tonto 5 minutos que toda la vida.

ARCANGEL Ha dicho:

OLA SR. ALEX KISIERA K ME AYUDARA PARA PODER ENCONTRAR UNA SENTENCIA PARA PODER LISTAR LAS TABLAS DEL SISTEMA….SERIA DE MUI AGRADO K M BRINDARA SU AYUDA…D ANTE MANO MIL GRACIAS…

José Cabo Ha dicho:

Hola Arcangel,

Escribir en mayúsculas en internet y en la web es sinónimo de gritar por eso hay gente, yo me incluyo, que puede sentirse incomodada. Por favor, escribe en minúsculas.
Sobre tu duda, cuando Alex tenga un rato estoy seguro de que te echará una mano.

Alex Barros Ha dicho:

Buenas Arcangel. Como ha dicho José Cabo, te agradeceríamos que escribieras de forma adecuada.

Sobre tu duda, tendrás que explicar mejor el contexto, y qué es lo que deseas. Cuando hablas de “el sistema” a qué te refieres?

La forma de listar tablas, suele ser con PHP, y las funciones que este lenguaje ofrece para tratar con tablas de tipo MySQL (que encontrarás en esta dirección: http://es.php.net/manual/es/ref.mysql.php)

Un saludo.

Daniel Ha dicho:

Muy explicativo, gracias por compartirlo

Saludos!!

Alberto Ha dicho:

Muy buena explicación, saludos

del.icio.us meneame.net RSS

Buscar:



Tagcloud

Entradas Recientes

Meta: