Diferencia entre unión natural y unión interna

Respuestas:

250

Una diferencia significativa entre INNER JOIN y NATURAL JOIN es el número de columnas devueltas.

Considerar:

TableA                           TableB
+------------+----------+        +--------------------+    
|Column1     | Column2  |        |Column1  |  Column3 |
+-----------------------+        +--------------------+
| 1          |  2       |        | 1       |   3      |
+------------+----------+        +---------+----------+

El INNER JOINde la Tabla A y la Tabla B en la columna 1 volverá

SELECT * FROM TableA AS a INNER JOIN TableB AS b USING (Column1);
SELECT * FROM TableA AS a INNER JOIN TableB AS b ON a.Column1 = b.Column1;
+------------+-----------+---------------------+    
| a.Column1  | a.Column2 | b.Column1| b.Column3|
+------------------------+---------------------+
| 1          |  2        | 1        |   3      |
+------------+-----------+----------+----------+

El NATURAL JOINde TableA y TableB en Column1 devolverá:

SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+    
|Column1     | Column2  | Column3  |
+-----------------------+----------+
| 1          |  2       |   3      |
+------------+----------+----------+

Se evita la columna repetida.

(AFAICT de la gramática estándar, no puede especificar las columnas de unión en una unión natural; la unión se basa estrictamente en el nombre. Consulte también Wikipedia ).

( Hay una trampa en la combinación interna producción, el trabajo a.y b.las partes no estarían en los nombres de columna, sólo tendría column1, column2, column1, column3como los encabezados. )

Jonathan Leffler
fuente
2
Tengo dos tablas TableA (Column1, Column2) y TableB (Column2, Column3).
2 8
16
El colapso de columnas en la salida es el aspecto menos importante de una unión natural. Lo que necesita saber es que (A) se une automáticamente en los campos del mismo nombre y (B) que jodirá su mierda cuando menos lo espere. En mi mundo, usar una unión natural es motivo de despido.
8
@JonofAllTrades ¿Puedes explicar más sobre qué NATURAL JOINarruinará exactamente , por qué es inesperado y en qué mundo estás?
Bryson
35
Esto se aborda de alguna manera en la respuesta del usuario 166390. Digamos que tienes una unión natural entre Customersy Employees, uniéndote EmployeeID. EmployeesTambién tiene un ManagerIDcampo. Todo está bien. Entonces, algún día, alguien agrega un ManagerIDcampo a la Customerstabla. Su unión no se romperá (eso sería una misericordia), sino que ahora incluirá un segundo campo y funcionará incorrectamente . Por lo tanto, un cambio aparentemente inofensivo puede romper algo solo distantemente relacionado. MUY MAL. La única ventaja de una unión natural es ahorrar un poco de mecanografía, y la desventaja es sustancial.
2
@ Jonathan, con respecto a tu respuesta, dijiste que SELECT * FROM TableA INNER JOIN TableB USING (Column1)da 4 columnas. Esto no es correcto porque SELECT * FROM TableA INNER JOIN TableB USING (Column1)y SELECT * FROM TableA NATURAL JOIN TableBson iguales, ambos dan 3 columnas.
Pacerier
81
  • Una unión interna es aquella en la que se requiere la fila correspondiente en la tabla unida para que se devuelva una fila de la primera tabla
  • Una combinación externa es aquella en la que no se requiere la fila coincidente en la tabla unida para que se devuelva una fila de la primera tabla
  • Una combinación natural es una combinación (puede tener una natural lefto natural right) que asume que el criterio de combinación es donde las columnas con el mismo nombre en ambas tablas coinciden

Evitaría usar combinaciones naturales como la peste, porque las combinaciones naturales son:

  • no es sql estándar [SQL 92] y, por lo tanto, no es portátil, no es particularmente legible (por la mayoría de los codificadores de SQL) y posiblemente no sea compatible con varias herramientas / bibliotecas
  • no informativo; no se puede saber en qué columnas se están uniendo sin hacer referencia al esquema
  • sus condiciones de unión son invisiblemente vulnerables a los cambios de esquema: si hay varias columnas de unión natural y una de esas columnas se elimina de una tabla, la consulta aún se ejecutará, pero probablemente no correctamente y este cambio en el comportamiento será silencioso
  • apenas vale la pena el esfuerzo; solo ahorras unos 10 segundos de escritura
Bohemio
fuente
2
Creo que se debe mencionar izquierda / derecha para exterior (ya que se menciona exterior). Pero por lo demás, agradable y conciso: solo le faltan los bonitos diagramas de registro SQL de ejemplo.
2
IZQUIERDA NATURAL y DERECHO NATURAL también existen. Pero sí, aún evítalos.
MatBailie
1
@Bohemian, en cuanto a "evitarlos como la peste", existen casos de uso real para las uniones naturales por lo que resultan útiles. mariadb.com/kb/en/sql-99/natural-join "... Los" Libros NATURAL JOIN Checkouts"de aspecto casual solo son posibles cuando las convenciones de nombres de bases de datos son formales y se aplican ..."
Pacerier
2
@sqlvovel hay mucho mal con tu comentario, específicamente es incorrecto. Las columnas de unión no se pueden "especificar en una lista de selección". La definición de una unión natural es unirse en * todas las columnas con nombres similares *. Del documento de MySQL: La UNIÓN NATURAL [IZQUIERDA] de dos tablas se define como semánticamente equivalente a una UNIÓN INTERNA o UNA IZQUIERDA IZQUIERDA con una cláusula USING que nombra todas las columnas que existen en ambas tablas. . Y otra cosa: en la práctica es inútil, porque ides omnipresente e inútil unirse; los nombres de clave foránea habituales son tablename_id. Las uniones naturales son una mala, mala, mala idea.
Bohemio
2
No hay columnas dobles devueltas en mi consulta. Una de las ventajas de la semántica de NJ es que las columnas duplicadas nunca se devuelven. Su consulta anterior también era "menos segura" que la mía porque fallaría si se agregara una columna llamada "a" a t2 (porque la condición de unión sin alias es ambigua). Sospecho que sus prejuicios contra NJ se basan en el hecho de que no lo ha probado en un producto donde el SQL estándar es compatible. La pregunta aquí es sobre SQL, no MySQL, cosas muy diferentes. Aún no ha corregido su respuesta sobre que no es estándar.
nvogel
27

Una combinación natural es solo un atajo para evitar escribir, con la presunción de que la combinación es simple y coincide con campos del mismo nombre.

SELECT
  *
FROM
  table1
NATURAL JOIN
  table2
    -- implicitly uses `room_number` to join

Es lo mismo que...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON table1.room_number = table2.room_number

Sin embargo, lo que no puede hacer con el formato de acceso directo son combinaciones más complejas ...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON (table1.room_number = table2.room_number)
    OR (table1.room_number IS NULL AND table2.room_number IS NULL)
MatBailie
fuente
2
@JonathanLeffler - En MySQL, ciertamente.
MatBailie
3
OK, interesante. Pregunté porque el estándar SQL no parece permitir esto (pero las extensiones siempre son posibles).
Jonathan Leffler
¿Qué DBMS permite esta sintaxis no estándar NATURAL JOIN ... USING ():? El estándar es a NATURAL JOIN boa JOIN b USING (c)
ypercubeᵀᴹ
1
"solo un atajo para evitar escribir" es una declaración errónea. Su característica más importante es que no da como resultado columnas duplicadas.
cuando
... por ejemplo, el resultado de su consulta que usa unión natural tendrá solo una columna con nombre room_number, mientras que sus uniones internas tendrán dos columnas con nombre room_number.
cuando
13

SQL no es fiel al modelo relacional de muchas maneras. El resultado de una consulta SQL no es una relación porque puede tener columnas con nombres duplicados, columnas 'anónimas' (sin nombre), filas duplicadas, nulos, etc. SQL no trata las tablas como relaciones porque se basa en el orden de las columnas, etc.

La idea detrás NATURAL JOINde SQL es hacer que sea más fácil ser más fiel al modelo relacional. El resultado de las NATURAL JOINdos tablas tendrá columnas desduplicadas por nombre, por lo tanto, no habrá columnas anónimas. Del mismo modo, UNION CORRESPONDINGy EXCEPT CORRESPONDINGse proporcionan para abordar la dependencia de SQL en el orden de las columnas en la UNIONsintaxis heredada .

Sin embargo, como con todas las técnicas de programación, se requiere disciplina para ser útil. Uno de los requisitos para un éxito NATURAL JOINes nombrar columnas consistentemente, porque las uniones están implícitas en columnas con los mismos nombres (es una pena que la sintaxis para renombrar columnas en SQL sea detallada, pero el efecto secundario es fomentar la disciplina al nombrar columnas en tablas base y VIEWs :)

Tenga en cuenta que un SQL NATURAL JOINes un equi-join **, sin embargo, esto no es obstáculo para la utilidad. Tenga en cuenta que si NATURAL JOINfuera el único tipo de combinación admitido en SQL, aún estaría relacionalmente completo .

Si bien es cierto que cualquiera NATURAL JOINpuede escribirse usando INNER JOINy proyección ( SELECT), también es cierto que cualquiera INNER JOINpuede escribirse usando producto ( CROSS JOIN) y restricción ( WHERE); Tenga en cuenta además que una NATURAL JOINtabla entre sin nombres de columna en común dará el mismo resultado que CROSS JOIN. Entonces, si solo le interesan los resultados que son relaciones (¡¿y por qué no ?!), entonces NATURAL JOINes el único tipo de unión que necesita. Claro, es cierto que desde una perspectiva de diseño de lenguaje, las abreviaturas como INNER JOINy CROSS JOINtienen su valor, pero también consideran que casi cualquier consulta SQL puede escribirse en 10 formas sintácticamente diferentes, pero semánticamente equivalentes, y esto es lo que hace que los optimizadores SQL sean tan difíciles desarrollar.

Aquí hay algunas consultas de ejemplo (usando la base de datos habitual de partes y proveedores ) que son semánticamente equivalentes:

SELECT *
  FROM S NATURAL JOIN SP;

-- Must disambiguate and 'project away' duplicate SNO attribute
SELECT S.SNO, SNAME, STATUS, CITY, PNO, QTY
  FROM S INNER JOIN SP 
          USING (SNO);                        

-- Alternative projection
SELECT S.*, PNO, QTY
  FROM S INNER JOIN SP 
          ON S.SNO = SP.SNO;

-- Same columns, different order == equivalent?!
SELECT SP.*, S.SNAME, S.STATUS, S.CITY
  FROM S INNER JOIN SP 
      ON S.SNO = SP.SNO;

-- 'Old school'
SELECT S.*, PNO, QTY
  FROM S, SP 
 WHERE S.SNO = SP.SNO;

** La unión natural relacional no es un equijoin, es una proyección de uno. - filipina

un día cuando
fuente
La unión natural relacional no es un equijoin, es una proyección de uno. La combinación natural de SQL es un equijoin de SQL (posibles duplicados): se define en términos de uso de combinación interna.
Filipinas
@philipxy: Gracias, he hecho enmiendas. Por favor, siéntase libre de editar, esta o cualquiera de mis respuestas, por errores o malentendidos. Todavía estoy aprendiendo de ti :)
cuando el
9

Una NATURALunión es solo una sintaxis corta para una unión específica INNER , o "equi-join", y, una vez que se desenvuelve la sintaxis, ambas representan la misma operación de álgebra relacional. No es un "tipo diferente" de unión, como en el caso de OUTER( LEFT/ RIGHT) o CROSSuniones.

Vea la sección equi-join en Wikipedia:

Una unión natural ofrece una mayor especialización de equi-une. El predicado de unión surge implícitamente al comparar todas las columnas en ambas tablas que tienen los mismos nombres de columna en las tablas unidas. La tabla unida resultante contiene solo una columna para cada par de columnas con el mismo nombre.

La mayoría de los expertos están de acuerdo en que las UNIONES NATURALES son peligrosas y, por lo tanto, desaconsejan su uso. El peligro viene de agregar inadvertidamente una nueva columna, llamada igual que otra columna ...

Es decir, todas las NATURALcombinaciones pueden escribirse como INNERcombinaciones (pero lo contrario no es cierto). Para hacerlo, simplemente cree el predicado explícitamente , por ejemplo, USINGo ON- y, como señaló Jonathan Leffler, seleccione las columnas deseadas del conjunto de resultados para evitar "duplicados" si lo desea.

Feliz codificación


(La NATURALpalabra clave también se puede aplicar LEFTy RIGHTunirse, y lo mismo se aplica. Una NATURAL LEFT/RIGHTcombinación es solo una sintaxis corta para una combinación específica LEFT/RIGHT ).

Comunidad
fuente
2
"La combinación NATURAL es solo una sintaxis corta para" equi-join "[cortada] - y, una vez que la sintaxis se desenvuelve, ambas representan el mismo álgebra relacional" - estás en lo cierto: eso es cierto para el álgebra relacional pero tu respuesta se desglosa después de eso, por ejemplo, "La mayoría de los expertos están de acuerdo en que las UNIONES NATURALES son peligrosas y, por lo tanto, desaconsejan su uso", ¿qué expertos en álgebra relacional dicen eso?
cuando el
2

Unión natural: es la combinación o el resultado combinado de todas las columnas de las dos tablas. Devolverá todas las filas de la primera tabla con respecto a la segunda tabla.

Unión interna: esta unión funcionará a menos que alguno de los nombres de columna sea sxame en dos tablas

Victor Bhatti
fuente
3
No creo que su respuesta sea lo suficientemente clara y tomaría una gran reescritura para solucionarlo.
cuando
0

Una unión natural es donde se unen 2 tablas sobre la base de todas las columnas comunes.

columna común: es una columna que tiene el mismo nombre en ambas tablas + tiene tipos de datos compatibles en ambas tablas. Puede usar solo = operador

Una unión interna es donde se unen 2 tablas sobre la base de columnas comunes mencionadas en la cláusula ON.

columna común: es una columna que tiene tipos de datos compatibles en ambas tablas pero no necesita tener el mismo nombre. Sólo se puede utilizar cualquier operador de comparación como =, <=, >=, <, >,<>

Suchitra Phadke
fuente
-2

la diferencia es que int la unión interna (equi / default) y la unión natural que en la columna común de natuarl join se mostrará en un solo tiempo, pero la unión interna / equi / default / simple de la columna común se mostrará el doble de tiempo.

Rajat Gupta
fuente
-2

La unión interna y la unión natural son casi iguales, pero hay una ligera diferencia entre ellas. La diferencia está en la unión natural, no es necesario especificar la condición, pero en la condición de unión interna es obligatoria. Si especificamos la condición en la unión interna, las tablas resultantes son como un producto cartesiano.

rashedcs
fuente
¿Por qué no hay necesidad de especificar condiciones de unión? ¿En qué circunstancias especificar condiciones en una unión interna daría como resultado un producto cartesiano?
cuando
Llamar a la unión externa e interna "casi lo mismo" es una leve subestimación en mi humilde opinión ... ¿tal vez puedas dar más detalles sobre tu evaluación?
TMOTTM
-3
mysql> SELECT  * FROM tb1 ;
+----+------+
| id | num  |
+----+------+
|  6 |   60 |
|  7 |   70 |
|  8 |   80 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

mysql> SELECT  * FROM tb2 ;
+----+------+
| id | num  |
+----+------+
|  4 |   40 |
|  5 |   50 |
|  9 |   90 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

UNIR INTERNAMENTE :

mysql> SELECT  * FROM tb1 JOIN tb2 ; 
+----+------+----+------+
| id | num  | id | num  |
+----+------+----+------+
|  6 |   60 |  4 |   40 |
|  7 |   70 |  4 |   40 |
|  8 |   80 |  4 |   40 |
|  1 |    1 |  4 |   40 |
|  2 |    2 |  4 |   40 |
|  3 |    3 |  4 |   40 |
|  6 |   60 |  5 |   50 |
|  7 |   70 |  5 |   50 |
|  8 |   80 |  5 |   50 |
.......more......
return 36 rows in set (0.01 sec) 
AND NATURAL JOIN :

    mysql> SELECT  * FROM tb1 NATURAL JOIN tb2 ;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |    1 |
    |  2 |    2 |
    |  3 |    3 |
    +----+------+
    3 rows in set (0.01 sec)
zloctb
fuente
-4

Unión interna, une dos tablas donde el nombre de la columna es el mismo.

Unión natural, une dos tablas donde el nombre de columna y los tipos de datos son iguales.

Tejeshwar
fuente
Esto es completamente incorrecto. A NATURAL JOIN(como señalaron varias personas hace años) es uno donde los nombres de columna son los mismos. El tipo de datos no necesita ser el mismo. Los campos utilizados para una INNER JOINnecesidad no tienen el mismo nombre.