Las combinaciones @avi izquierda y derecha son similares, si no le molesta cuál es la tabla principal en la que se basa la combinación.
Anup
2
@philipxy: Esa es una definición extraña (incluso si tienes razón). Pero prefiero ir al revés y comenzar con la unión cruzada y luego "construir" la unión interna encima. Después de todo, el mero concepto de unión cruzada invalida estas visualizaciones de diagrama de Venn informales e inexactas ...
Lukas Eder
1
Estas imágenes parecen implicar que la unión es igual a la unión externa completa y la intersección es la misma que la unión interna, lo que no es correcto hasta donde yo sé.
mightyWOZ
1
@DevDave, porque contrario a la creencia popular, una imagen no vale más que mil palabras. Ver siguiente respuesta.
hyankov
248
¿Qué es SQL JOIN?
SQL JOIN es un método para recuperar datos de dos o más tablas de bases de datos.
En este tipo de a JOIN, obtenemos todos los registros que coinciden con la condición en ambas tablas, y los registros en ambas tablas que no coinciden no se informan.
En otras palabras, INNER JOINse basa en el hecho único de que: SOLO las entradas coincidentes en AMBAS tablas DEBEN aparecer en la lista.
Tenga en cuenta que una JOINsin otras JOINpalabras clave (como INNER, OUTER, LEFT, etc) es una INNER JOIN. En otras palabras, JOINes un azúcar sintáctico para INNER JOIN(ver: Diferencia entre JOIN y INNER JOIN ).
2. ÚNETE EXTERIOR:
OUTER JOIN recupera
O bien, las filas coincidentes de una tabla y todas las filas de la otra tabla O, todas las filas de todas las tablas (no importa si hay una coincidencia).
Hay tres tipos de unión externa:
2.1 IZQUIERDA EXTERIOR O IZQUIERDA
Esta unión devuelve todas las filas de la tabla izquierda junto con las filas coincidentes de la tabla derecha. Si no hay columnas que coincidan en la tabla de la derecha, devuelve NULLvalores.
2.2 UNIÓN EXTERIOR DERECHA o UNIÓN DERECHA
Esto JOINdevuelve todas las filas de la tabla derecha junto con las filas coincidentes de la tabla izquierda. Si no hay columnas que coincidan en la tabla izquierda, devuelve NULLvalores.
2.3 FULL OUTER JOIN o FULL JOIN
Esto JOINcombina LEFT OUTER JOINy RIGHT OUTER JOIN. Devuelve filas de cualquier tabla cuando se cumplen las condiciones y devuelve NULLvalor cuando no hay coincidencia.
En otras palabras, OUTER JOINse basa en el hecho de que: SOLO las entradas coincidentes en UNA de las tablas (DERECHA o IZQUIERDA) o AMBAS de las tablas (COMPLETO) DEBEN aparecer en la lista.
Note that `OUTERJOIN`is a loosened form of`INNERJOIN`.
3. UNIÓN NATURAL:
Se basa en las dos condiciones:
el JOINse hace en todas las columnas con el mismo nombre de la igualdad.
Elimina columnas duplicadas del resultado.
Esto parece ser más de naturaleza teórica y como resultado (probablemente) la mayoría de los DBMS ni siquiera se molestan en apoyar esto.
4. UNIÓN CRUZADA:
Es el producto cartesiano de las dos tablas involucradas. El resultado de un CROSS JOINtestamento no tiene sentido en la mayoría de las situaciones. Además, no necesitaremos esto en absoluto (o necesita lo menos, para ser precisos).
5. AUTO UNIRSE:
No es una forma diferente de JOIN, más bien es una JOIN( INNER, OUTER, etc.) de una tabla consigo misma.
ÚNETES basados en operadores
Dependiendo del operador utilizado para una JOINcláusula, puede haber dos tipos de JOINs. Son
Equi ÚNETE
Theta ÚNETE
1. Equi ÚNETE:
Para cualquier JOINtipo ( INNER, OUTER, etc.), si usamos sólo el operador de igualdad (=), entonces se dice que el JOINes una EQUI JOIN.
2. Theta ÚNETE:
Esto es igual EQUI JOINpero permite a todos los demás operadores como>, <,> = etc.
Muchos consideran ambos EQUI JOINy Theta JOINsimilares a INNER, OUTER
etc. JOINs. Pero creo firmemente que es un error y hace que las ideas sean vagas. Porque INNER JOIN, OUTER JOINetc están todos conectados con las tablas y sus datos, mientras que EQUI JOINy THETA JOINsolamente están conectados con los operadores que utilizamos en el primero.
Nuevamente, hay muchos que consideran NATURAL JOINcomo una especie de "peculiar" EQUI JOIN. De hecho, es cierto, debido a la primera condición que mencioné NATURAL JOIN. Sin embargo, no tenemos que restringir eso simplemente a NATURAL JOINs solo. INNER JOINs, s, OUTER JOINetc., podría ser un EQUI JOINtambién.
Hay relativamente nuevas LATERAL JOIN .. SELECT * FROM r1, LATERAL fx (r1)
Pavel Stehule
13
Si bien esto parece razonable, no creo que responda "qué es una unión SQL" de ninguna manera que transmita información útil. La respuesta en su conjunto es una referencia escrita para personas que ya entienden las uniones, no para el tipo de personas que hacen esas preguntas. También omite referencias, tanto para respaldar sus afirmaciones (como es apropiado si se hace una respuesta autorizada) como para proporcionar una explicación adicional a través de recursos externos. Si está tratando de escribir una respuesta autorizada para vincular a los nuevos usuarios de SQL, podría valer la pena rellenar un poco los espacios en blanco, especialmente la parte "qué es una unión".
Craig Ringer
¿Puedes dar algunos ejemplos?
avi
67
Definición:
JOINS es una forma de consultar los datos que se combinaron de varias tablas simultáneamente.
Tipos de uniones:
En cuanto a RDBMS, hay 5 tipos de combinaciones:
Equi-Join: combina registros comunes de dos tablas según la condición de igualdad. Técnicamente, la unión se realiza utilizando el operador de igualdad (=) para comparar los valores de la clave primaria de una tabla y los valores de la clave externa de otra tabla, por lo tanto, el conjunto de resultados incluye registros comunes (coincidentes) de ambas tablas. Para la implementación, vea INNER-JOIN.
Natural-Join: es una versión mejorada de Equi-Join, en la que la operación SELECT omite la columna duplicada. Para implementación ver INNER-JOIN
No-Equi-Join: es inverso a Equi-join donde la condición de unión se utiliza con un operador distinto de igual (=) por ejemplo,! =, <=,> =,>, <O ENTRE, etc. Para la implementación, vea INNER-JOIN.
Self-Join:: Un comportamiento personalizado de join donde una tabla se combina consigo misma; Esto normalmente se necesita para consultar tablas de autorreferencia (o entidad de relación unaria). Para la implementación ver INNER-JOINs.
Producto cartesiano: combina de forma cruzada todos los registros de ambas tablas sin ninguna condición. Técnicamente, devuelve el conjunto de resultados de una consulta sin WHERE-Cláusula.
Según el avance y la preocupación de SQL, hay 3 tipos de combinaciones y todas las combinaciones RDBMS se pueden lograr utilizando estos tipos de combinaciones.
INNER-JOIN: combina (o combina) filas coincidentes de dos tablas. La coincidencia se realiza en base a columnas comunes de tablas y su operación de comparación. Si la condición se basa en la igualdad, entonces: EQUI-JOIN realizó, de lo contrario, no EQUI-Join.
OUTER-JOIN: combina (o combina) filas coincidentes de dos tablas y filas no coincidentes con valores NULL. Sin embargo, se puede personalizar la selección de filas no coincidentes, por ejemplo, seleccionando una fila no coincidente de la primera tabla o la segunda tabla por subtipos: IZQUIERDA EXTERIOR IZQUIERDA y UNIÓN EXTERIOR DERECHA.
2.1. LEFT Outer JOIN (también conocido como LEFT-JOIN): devuelve filas coincidentes de dos tablas y no coincidentes de la tabla LEFT (es decir, la primera tabla) solamente.
2.2. UNIÓN EXTERIOR DERECHA (también conocido como UNIÓN DERECHA): devuelve filas coincidentes de dos tablas y no coincidentes solo de la tabla DERECHA.
2.3. FULL OUTER JOIN (también conocido como OUTER JOIN): devuelve coincidencias y no coincidencias de ambas tablas.
CROSS-JOIN: esta unión no combina / combina sino que realiza un producto cartesiano.
Nota: Self-JOIN puede lograrse ya sea INNER-JOIN, OUTER-JOIN y CROSS-JOIN según los requisitos, pero la tabla debe unirse consigo misma.
Las etiquetas "Tabla 1" y "Tabla 2" y las etiquetas debajo son inapropiadas, son de ilustraciones de intersect/ except/ union; aquí los círculos son las filas devueltas por left& rightjoin, como dicen las etiquetas numeradas. La imagen de AXB no tiene sentido. cross join= inner join on 1=1& es un caso especial del primer diagrama.
Filipinas
Vale la pena mencionar que SQL-92 define el UNION JOIN. Ahora queda obsoleto en SQL: 2003.
The Impaler
40
Curiosamente, la mayoría de las otras respuestas sufren de estos dos problemas:
Primero y principal: JOINs son productos cartesianos
Es por eso que los diagramas de Venn los explican de manera tan inexacta, porque un JOIN crea un producto cartesiano entre las dos tablas unidas. Wikipedia lo ilustra muy bien:
La sintaxis SQL para productos cartesianos es CROSS JOIN. Por ejemplo:
SELECT*-- This just generates all the days in January 2017FROM generate_series('2017-01-01'::TIMESTAMP,'2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
INTERVAL '1 day')AS days(day)-- Here, we're combining all days with all departmentsCROSSJOIN departments
Que combina todas las filas de una tabla con todas las filas de la otra tabla:
Fuente:
+--------+ +------------+
| day | | department |
+--------+ +------------+
| Jan 01 | | Dept 1 |
| Jan 02 | | Dept 2 |
| ... | | Dept 3 |
| Jan 30 | +------------+
| Jan 31 |
+--------+
Resultado:
+--------+------------+
| day | department |
+--------+------------+
| Jan 01 | Dept 1 |
| Jan 01 | Dept 2 |
| Jan 01 | Dept 3 |
| Jan 02 | Dept 1 |
| Jan 02 | Dept 2 |
| Jan 02 | Dept 3 |
| ... | ... |
| Jan 31 | Dept 1 |
| Jan 31 | Dept 2 |
| Jan 31 | Dept 3 |
+--------+------------+
Si solo escribimos una lista de tablas separadas por comas, obtendremos lo mismo:
-- CROSS JOINing two tables:SELECT*FROM table1, table2
UNIÓN INTERNA (Theta-JOIN)
Un INNER JOINes solo un filtro CROSS JOINdonde el predicado de filtro se llama Thetaen álgebra relacional.
Por ejemplo:
SELECT*-- Same as beforeFROM generate_series('2017-01-01'::TIMESTAMP,'2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
INTERVAL '1 day')AS days(day)-- Now, exclude all days/departments combinations for-- days before the department was createdJOIN departments AS d ON day >= d.created_at
Tenga en cuenta que la palabra clave INNERes opcional (excepto en MS Access).
Un tipo especial de Theta-JOIN es equi JOIN, que más usamos. El predicado une la clave primaria de una tabla con la clave externa de otra tabla. Si usamos la base de datos Sakila para ilustración, podemos escribir:
SELECT*FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id
Esto combina a todos los actores con sus películas.
O también, en algunas bases de datos:
SELECT*FROM actor
JOIN film_actor USING(actor_id)JOIN film USING(film_id)
La USING()sintaxis permite especificar una columna que debe estar presente a ambos lados de las tablas de una operación JOIN y crea un predicado de igualdad en esas dos columnas.
UNIÓN NATURAL
Otras respuestas han enumerado este "tipo de UNIÓN" por separado, pero eso no tiene sentido. Es solo una forma de sintaxis de azúcar para equi JOIN, que es un caso especial de Theta-JOIN o INNER JOIN. UNIÓN NATURAL simplemente recopila todas las columnas que son comunes a ambas tablas que se unen y las une USING(). Lo cual casi nunca es útil, debido a coincidencias accidentales (como LAST_UPDATEcolumnas en la base de datos Sakila ).
Aquí está la sintaxis:
SELECT*FROM actor
NATURALJOIN film_actor
NATURALJOIN film
ÚNETE EXTERIOR
Ahora, OUTER JOINes un poco diferente INNER JOINya que crea UNIONvarios productos cartesianos. Podemos escribir:
-- Convenient syntax:SELECT*FROM a LEFTJOIN b ON<predicate>-- Cumbersome, equivalent syntax:SELECT a.*, b.*FROM a JOIN b ON<predicate>UNIONALLSELECT a.*,NULL,NULL,...,NULLFROM a
WHERENOTEXISTS(SELECT*FROM b WHERE<predicate>)
Nadie quiere escribir lo último, por lo que escribimos OUTER JOIN(que generalmente está mejor optimizado por las bases de datos).
Como INNER, la palabra clave OUTERes opcional, aquí.
OUTER JOIN viene en tres sabores:
LEFT [ OUTER ] JOIN: La tabla izquierda de la JOINexpresión se agrega a la unión como se muestra arriba.
RIGHT [ OUTER ] JOIN: La tabla derecha de la JOINexpresión se agrega a la unión como se muestra arriba.
FULL [ OUTER ] JOIN: Ambas tablas de la JOINexpresión se agregan a la unión como se muestra arriba.
Hay algunas sintaxis históricas y obsoletas en Oracle y SQL Server, que OUTER JOINya eran compatibles antes de que el estándar SQL tuviera una sintaxis para esto:
-- OracleSELECT*FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)AND fa.film_id = f.film_id(+)-- SQL ServerSELECT*FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id
Dicho esto, no use esta sintaxis. Solo enumero esto aquí para que pueda reconocerlo en publicaciones antiguas de blog / código heredado.
Particionado OUTER JOIN
Pocas personas saben esto, pero el estándar SQL especifica particionado OUTER JOIN(y Oracle lo implementa). Puedes escribir cosas como esta:
WITH-- Using CONNECT BY to generate all dates in January
days(day)AS(SELECT DATE '2017-01-01'+ LEVEL -1FROM dual
CONNECTBY LEVEL <=31),-- Our departments
departments(department, created_at)AS(SELECT'Dept 1', DATE '2017-01-10'FROM dual UNIONALLSELECT'Dept 2', DATE '2017-01-11'FROM dual UNIONALLSELECT'Dept 3', DATE '2017-01-12'FROM dual UNIONALLSELECT'Dept 4', DATE '2017-04-01'FROM dual UNIONALLSELECT'Dept 5', DATE '2017-04-02'FROM dual
)SELECT*FROM days
LEFTJOIN departments
PARTITIONBY(department)-- This is where the magic happensON day >= created_at
Partes del resultado:
+--------+------------+------------+
| day | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1 | | -- Didn't match, but still get row
| Jan 02 | Dept 1 | | -- Didn't match, but still get row
| ... | Dept 1 | | -- Didn't match, but still get row
| Jan 09 | Dept 1 | | -- Didn't match, but still get row
| Jan 10 | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 11 | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 12 | Dept 1 | Jan 10 | -- Matches, so get join result
| ... | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 31 | Dept 1 | Jan 10 | -- Matches, so get join result
El punto aquí es que todas las filas del lado particionado de la unión terminarán en el resultado independientemente de si JOINcoinciden con algo en el "otro lado de la UNIÓN". Larga historia corta: Esto es para llenar datos escasos en los informes. ¡Muy útil!
SEMI UNIRSE
¿Seriamente? Ninguna otra respuesta tiene esto? Por supuesto que no, porque desafortunadamente no tiene una sintaxis nativa en SQL (al igual que ANTI JOIN a continuación). Pero podemos usar IN()y EXISTS(), por ejemplo, para encontrar a todos los actores que han jugado en películas:
SELECT*FROM actor a
WHEREEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
El WHERE a.actor_id = fa.actor_idpredicado actúa como el predicado de semiunión. Si no lo cree, consulte los planes de ejecución, por ejemplo, en Oracle. Verá que la base de datos ejecuta una operación SEMI JOIN, no el EXISTS()predicado.
SELECT*FROM actor a
WHERENOTEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
Algunas personas (especialmente las personas de MySQL) también escriben ANTI JOIN de esta manera:
SELECT*FROM actor a
LEFTJOIN film_actor fa
USING(actor_id)WHERE film_id ISNULL
Creo que la razón histórica es el rendimiento.
UNIÓN LATERAL
Dios mío, este es demasiado genial. Soy el único en mencionarlo? Aquí hay una consulta genial:
SELECT a.first_name, a.last_name, f.*FROM actor AS a
LEFTOUTERJOIN LATERAL (SELECT f.title, SUM(amount)AS revenue
FROM film AS f
JOIN film_actor AS fa USING(film_id)JOIN inventory AS i USING(film_id)JOIN rental AS r USING(inventory_id)JOIN payment AS p USING(rental_id)WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
ON true
Encontrará el TOP 5 de películas productoras de ingresos por actor. Cada vez que necesite una consulta TOP-N-per-something, LATERAL JOINserá su amigo. Si eres una persona de SQL Server, entonces conoces este JOINtipo bajo el nombreAPPLY
SELECT a.first_name, a.last_name, f.*FROM actor AS a
OUTERAPPLY(SELECT f.title, SUM(amount)AS revenue
FROM film AS f
JOIN film_actor AS fa ON f.film_id = fa.film_id
JOIN inventory AS i ON f.film_id = i.film_id
JOIN rental AS r ON i.inventory_id = r.inventory_id
JOIN payment AS p ON r.rental_id = p.rental_id
WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
OK, tal vez eso es hacer trampa, porque una expresión LATERAL JOINo APPLYes realmente una "subconsulta correlacionada" que produce varias filas. Pero si permitimos "subconsultas correlacionadas", también podemos hablar de ...
MULTISET
Oracle e Informix solo lo implementan realmente (que yo sepa), pero se puede emular en PostgreSQL usando matrices y / o XML y en SQL Server usando XML.
MULTISETproduce una subconsulta correlacionada y anida el conjunto resultante de filas en la consulta externa. La consulta a continuación selecciona todos los actores y para cada actor recopila sus películas en una colección anidada:
SELECT a.*, MULTISET (SELECT f.*FROM film AS f
JOIN film_actor AS fa USING(film_id)WHERE a.actor_id = fa.actor_id
)AS films
FROM actor
Como se ha visto, hay más tipos de JOIN que sólo el "aburrido" INNER, OUTERy CROSS JOINque por lo general se mencionan. Más detalles en mi artículo . Y, por favor, deje de usar los diagramas de Venn para ilustrarlos.
Equijoin es el caso especial de theta-join donde theta es igualdad. Theta-join es análogo a un caso especial de unión interna donde on es una comparación theta de una columna de cada uno. Algunas décadas después de que Codd los definió, algunos libros de texto definieron erróneamente theta join como una generalización que es el análogo de la unión interna.
Filipinas
@philipxy: ¿Hay algo específico que deba cambiar en mi respuesta? Podría sugerir una edición ...
Lukas Eder
10
En mi opinión, he creado una ilustración que explica mejor que las palabras:
@Niraj Los círculos A y B no contienen las filas de A y B. Se copian ciegamente de otros lugares sin crédito. La unión cruzada se incluye en el caso de unión interna, es la unión interna en 1 = 1. ¿De qué manera estas partes de la imagen son "perfectas"?
philipxy
@philipxy Lo siento, pero no me preocupa si se copia desde otro lugar. y no estoy seguro de cuál no es correcto en la imagen de arriba. Para mí esto está bien. La unión cruzada no se describe aquí. No está incluido en una unión interna ..
Niraj
-3
Voy a presionar a mi mascota: la palabra clave USING.
Si ambas tablas en ambos lados de JOIN tienen sus claves foráneas correctamente nombradas (es decir, el mismo nombre, no solo "id"), esto se puede usar:
¿Qué es
SQL JOIN
?SQL JOIN
es un método para recuperar datos de dos o más tablas de bases de datos.¿Cuáles son los diferentes
SQL JOIN
s?Hay un total de cinco
JOIN
s. Son :1. UNIRSE O UNIRSE INTERIOR:
En este tipo de a
JOIN
, obtenemos todos los registros que coinciden con la condición en ambas tablas, y los registros en ambas tablas que no coinciden no se informan.En otras palabras,
INNER JOIN
se basa en el hecho único de que: SOLO las entradas coincidentes en AMBAS tablas DEBEN aparecer en la lista.Tenga en cuenta que una
JOIN
sin otrasJOIN
palabras clave (comoINNER
,OUTER
,LEFT
, etc) es unaINNER JOIN
. En otras palabras,JOIN
es un azúcar sintáctico paraINNER JOIN
(ver: Diferencia entre JOIN y INNER JOIN ).2. ÚNETE EXTERIOR:
OUTER JOIN
recuperaO bien, las filas coincidentes de una tabla y todas las filas de la otra tabla O, todas las filas de todas las tablas (no importa si hay una coincidencia).
Hay tres tipos de unión externa:
2.1 IZQUIERDA EXTERIOR O IZQUIERDA
Esta unión devuelve todas las filas de la tabla izquierda junto con las filas coincidentes de la tabla derecha. Si no hay columnas que coincidan en la tabla de la derecha, devuelve
NULL
valores.2.2 UNIÓN EXTERIOR DERECHA o UNIÓN DERECHA
Esto
JOIN
devuelve todas las filas de la tabla derecha junto con las filas coincidentes de la tabla izquierda. Si no hay columnas que coincidan en la tabla izquierda, devuelveNULL
valores.2.3 FULL OUTER JOIN o FULL JOIN
Esto
JOIN
combinaLEFT OUTER JOIN
yRIGHT OUTER JOIN
. Devuelve filas de cualquier tabla cuando se cumplen las condiciones y devuelveNULL
valor cuando no hay coincidencia.En otras palabras,
OUTER JOIN
se basa en el hecho de que: SOLO las entradas coincidentes en UNA de las tablas (DERECHA o IZQUIERDA) o AMBAS de las tablas (COMPLETO) DEBEN aparecer en la lista.3. UNIÓN NATURAL:
Se basa en las dos condiciones:
JOIN
se hace en todas las columnas con el mismo nombre de la igualdad.Esto parece ser más de naturaleza teórica y como resultado (probablemente) la mayoría de los DBMS ni siquiera se molestan en apoyar esto.
4. UNIÓN CRUZADA:
Es el producto cartesiano de las dos tablas involucradas. El resultado de un
CROSS JOIN
testamento no tiene sentido en la mayoría de las situaciones. Además, no necesitaremos esto en absoluto (o necesita lo menos, para ser precisos).5. AUTO UNIRSE:
No es una forma diferente de
JOIN
, más bien es unaJOIN
(INNER
,OUTER
, etc.) de una tabla consigo misma.ÚNETES basados en operadores
Dependiendo del operador utilizado para una
JOIN
cláusula, puede haber dos tipos deJOIN
s. Son1. Equi ÚNETE:
Para cualquier
JOIN
tipo (INNER
,OUTER
, etc.), si usamos sólo el operador de igualdad (=), entonces se dice que elJOIN
es unaEQUI JOIN
.2. Theta ÚNETE:
Esto es igual
EQUI JOIN
pero permite a todos los demás operadores como>, <,> = etc.fuente
Definición:
JOINS es una forma de consultar los datos que se combinaron de varias tablas simultáneamente.
Tipos de uniones:
En cuanto a RDBMS, hay 5 tipos de combinaciones:
Equi-Join: combina registros comunes de dos tablas según la condición de igualdad. Técnicamente, la unión se realiza utilizando el operador de igualdad (=) para comparar los valores de la clave primaria de una tabla y los valores de la clave externa de otra tabla, por lo tanto, el conjunto de resultados incluye registros comunes (coincidentes) de ambas tablas. Para la implementación, vea INNER-JOIN.
Natural-Join: es una versión mejorada de Equi-Join, en la que la operación SELECT omite la columna duplicada. Para implementación ver INNER-JOIN
No-Equi-Join: es inverso a Equi-join donde la condición de unión se utiliza con un operador distinto de igual (=) por ejemplo,! =, <=,> =,>, <O ENTRE, etc. Para la implementación, vea INNER-JOIN.
Self-Join:: Un comportamiento personalizado de join donde una tabla se combina consigo misma; Esto normalmente se necesita para consultar tablas de autorreferencia (o entidad de relación unaria). Para la implementación ver INNER-JOINs.
Producto cartesiano: combina de forma cruzada todos los registros de ambas tablas sin ninguna condición. Técnicamente, devuelve el conjunto de resultados de una consulta sin WHERE-Cláusula.
Según el avance y la preocupación de SQL, hay 3 tipos de combinaciones y todas las combinaciones RDBMS se pueden lograr utilizando estos tipos de combinaciones.
INNER-JOIN: combina (o combina) filas coincidentes de dos tablas. La coincidencia se realiza en base a columnas comunes de tablas y su operación de comparación. Si la condición se basa en la igualdad, entonces: EQUI-JOIN realizó, de lo contrario, no EQUI-Join.
OUTER-JOIN: combina (o combina) filas coincidentes de dos tablas y filas no coincidentes con valores NULL. Sin embargo, se puede personalizar la selección de filas no coincidentes, por ejemplo, seleccionando una fila no coincidente de la primera tabla o la segunda tabla por subtipos: IZQUIERDA EXTERIOR IZQUIERDA y UNIÓN EXTERIOR DERECHA.
2.1. LEFT Outer JOIN (también conocido como LEFT-JOIN): devuelve filas coincidentes de dos tablas y no coincidentes de la tabla LEFT (es decir, la primera tabla) solamente.
2.2. UNIÓN EXTERIOR DERECHA (también conocido como UNIÓN DERECHA): devuelve filas coincidentes de dos tablas y no coincidentes solo de la tabla DERECHA.
2.3. FULL OUTER JOIN (también conocido como OUTER JOIN): devuelve coincidencias y no coincidencias de ambas tablas.
CROSS-JOIN: esta unión no combina / combina sino que realiza un producto cartesiano.
Nota: Self-JOIN puede lograrse ya sea INNER-JOIN, OUTER-JOIN y CROSS-JOIN según los requisitos, pero la tabla debe unirse consigo misma.
Para más información:
Ejemplos:
1.1: INNER-JOIN: implementación de Equi-join
1.2: INNER-JOIN: implementación de Natural-JOIN
1.3: INNER-JOIN con implementación NO-Equi-join
1.4: INNER-JOIN con AUTO-JOIN
2.1: UNIÓN EXTERNA (unión externa completa)
2.2: IZQUIERDA
2.3: UNIÓN DERECHA
3.1: UNIÓN CRUZADA
3.2: CROSS JOIN-Self JOIN
//O//
fuente
intersect
/except
/union
; aquí los círculos son las filas devueltas porleft
&right
join
, como dicen las etiquetas numeradas. La imagen de AXB no tiene sentido.cross join
=inner join on 1=1
& es un caso especial del primer diagrama.UNION JOIN
. Ahora queda obsoleto en SQL: 2003.Curiosamente, la mayoría de las otras respuestas sufren de estos dos problemas:
Recientemente escribí un artículo sobre el tema: Una guía completa, probablemente incompleta, sobre las diferentes formas de unir tablas en SQL , que resumiré aquí.
Primero y principal: JOINs son productos cartesianos
Es por eso que los diagramas de Venn los explican de manera tan inexacta, porque un JOIN crea un producto cartesiano entre las dos tablas unidas. Wikipedia lo ilustra muy bien:
La sintaxis SQL para productos cartesianos es
CROSS JOIN
. Por ejemplo:Que combina todas las filas de una tabla con todas las filas de la otra tabla:
Fuente:
Resultado:
Si solo escribimos una lista de tablas separadas por comas, obtendremos lo mismo:
UNIÓN INTERNA (Theta-JOIN)
Un
INNER JOIN
es solo un filtroCROSS JOIN
donde el predicado de filtro se llamaTheta
en álgebra relacional.Por ejemplo:
Tenga en cuenta que la palabra clave
INNER
es opcional (excepto en MS Access).( mira el artículo para ver ejemplos de resultados )
EQUI JOIN
Un tipo especial de Theta-JOIN es equi JOIN, que más usamos. El predicado une la clave primaria de una tabla con la clave externa de otra tabla. Si usamos la base de datos Sakila para ilustración, podemos escribir:
Esto combina a todos los actores con sus películas.
O también, en algunas bases de datos:
La
USING()
sintaxis permite especificar una columna que debe estar presente a ambos lados de las tablas de una operación JOIN y crea un predicado de igualdad en esas dos columnas.UNIÓN NATURAL
Otras respuestas han enumerado este "tipo de UNIÓN" por separado, pero eso no tiene sentido. Es solo una forma de sintaxis de azúcar para equi JOIN, que es un caso especial de Theta-JOIN o INNER JOIN. UNIÓN NATURAL simplemente recopila todas las columnas que son comunes a ambas tablas que se unen y las une
USING()
. Lo cual casi nunca es útil, debido a coincidencias accidentales (comoLAST_UPDATE
columnas en la base de datos Sakila ).Aquí está la sintaxis:
ÚNETE EXTERIOR
Ahora,
OUTER JOIN
es un poco diferenteINNER JOIN
ya que creaUNION
varios productos cartesianos. Podemos escribir:Nadie quiere escribir lo último, por lo que escribimos
OUTER JOIN
(que generalmente está mejor optimizado por las bases de datos).Como
INNER
, la palabra claveOUTER
es opcional, aquí.OUTER JOIN
viene en tres sabores:LEFT [ OUTER ] JOIN
: La tabla izquierda de laJOIN
expresión se agrega a la unión como se muestra arriba.RIGHT [ OUTER ] JOIN
: La tabla derecha de laJOIN
expresión se agrega a la unión como se muestra arriba.FULL [ OUTER ] JOIN
: Ambas tablas de laJOIN
expresión se agregan a la unión como se muestra arriba.Todo esto se puede combinar con la palabra clave
USING()
o conNATURAL
(en realidad, he tenido un caso de uso del mundo real para unNATURAL FULL JOIN
reciente )Sintaxis Alternativas
Hay algunas sintaxis históricas y obsoletas en Oracle y SQL Server, que
OUTER JOIN
ya eran compatibles antes de que el estándar SQL tuviera una sintaxis para esto:Dicho esto, no use esta sintaxis. Solo enumero esto aquí para que pueda reconocerlo en publicaciones antiguas de blog / código heredado.
Particionado
OUTER JOIN
Pocas personas saben esto, pero el estándar SQL especifica particionado
OUTER JOIN
(y Oracle lo implementa). Puedes escribir cosas como esta:Partes del resultado:
El punto aquí es que todas las filas del lado particionado de la unión terminarán en el resultado independientemente de si
JOIN
coinciden con algo en el "otro lado de la UNIÓN". Larga historia corta: Esto es para llenar datos escasos en los informes. ¡Muy útil!SEMI UNIRSE
¿Seriamente? Ninguna otra respuesta tiene esto? Por supuesto que no, porque desafortunadamente no tiene una sintaxis nativa en SQL (al igual que ANTI JOIN a continuación). Pero podemos usar
IN()
yEXISTS()
, por ejemplo, para encontrar a todos los actores que han jugado en películas:El
WHERE a.actor_id = fa.actor_id
predicado actúa como el predicado de semiunión. Si no lo cree, consulte los planes de ejecución, por ejemplo, en Oracle. Verá que la base de datos ejecuta una operación SEMI JOIN, no elEXISTS()
predicado.ANTI UNIRSE
Esto es justo lo contrario de SEMI JOIN ( tener cuidado de no usar
NOT IN
embargo , ya que tiene una importante advertencia)Aquí están todos los actores sin películas:
Algunas personas (especialmente las personas de MySQL) también escriben ANTI JOIN de esta manera:
Creo que la razón histórica es el rendimiento.
UNIÓN LATERAL
Dios mío, este es demasiado genial. Soy el único en mencionarlo? Aquí hay una consulta genial:
Encontrará el TOP 5 de películas productoras de ingresos por actor. Cada vez que necesite una consulta TOP-N-per-something,
LATERAL JOIN
será su amigo. Si eres una persona de SQL Server, entonces conoces esteJOIN
tipo bajo el nombreAPPLY
OK, tal vez eso es hacer trampa, porque una expresión
LATERAL JOIN
oAPPLY
es realmente una "subconsulta correlacionada" que produce varias filas. Pero si permitimos "subconsultas correlacionadas", también podemos hablar de ...MULTISET
Oracle e Informix solo lo implementan realmente (que yo sepa), pero se puede emular en PostgreSQL usando matrices y / o XML y en SQL Server usando XML.
MULTISET
produce una subconsulta correlacionada y anida el conjunto resultante de filas en la consulta externa. La consulta a continuación selecciona todos los actores y para cada actor recopila sus películas en una colección anidada:Como se ha visto, hay más tipos de JOIN que sólo el "aburrido"
INNER
,OUTER
yCROSS JOIN
que por lo general se mencionan. Más detalles en mi artículo . Y, por favor, deje de usar los diagramas de Venn para ilustrarlos.fuente
En mi opinión, he creado una ilustración que explica mejor que las palabras:
fuente
Voy a presionar a mi mascota: la palabra clave USING.
Si ambas tablas en ambos lados de JOIN tienen sus claves foráneas correctamente nombradas (es decir, el mismo nombre, no solo "id"), esto se puede usar:
Esto me parece muy práctico, legible y no se usa con la frecuencia suficiente.
fuente