Movatterモバイル変換


[0]ホーム

URL:


Ir al contenido
WikipediaLa enciclopedia libre
Buscar

Sentencia JOIN en SQL

De Wikipedia, la enciclopedia libre
Este artículo o sección necesita serwikificado, por favor,edítalo para que cumpla con lasconvenciones de estilo.
Puedes avisar al redactor principal pegando lo siguiente en su página de discusión:{{sust:Aviso wikificar|Sentencia JOIN en SQL}} ~~~~
Uso de esta plantilla:{{Wikificar|t={{sust:CURRENTTIMESTAMP}}}}
Joins del SQL y sus representaciones comodiagramas de Venn

La sentenciaJOIN (unir, combinar) deSQL permite combinarregistros de una o mástablas en unabase de datos. En el Lenguaje de Consultas Estructurado (SQL) hay tres tipos deJOIN: interno, externo y cruzado. El estándar ANSI del SQL especifica cinco tipos deJOIN:INNER,LEFT OUTER,RIGHT OUTER,FULL OUTER yCROSS. Una tabla puede unirse a sí misma, produciendo una auto-combinación, SELF-JOIN.

Matemáticamente,JOIN es composición relacional, la operación fundamental en elálgebra relacional, y, generalizando, es una función decomposición.

Tablas de ejemplo

[editar]

Todas las explicaciones que están a continuación usan las siguientes dos tablas para ilustrar el efecto de diferentes clases de uniones JOIN.

Empleado
ApellidoIDDepartamento
Andrade31
Jordán33
Steinberg33
Róbinson34
Zolano34
Gaspar36
Departamento
NombreDepartamentoIDDepartamento
Ventas31
Ingeniería33
Producción34
Mercadeo35

La tablaEmpleado contiene los apellidos de los empleados junto al número del departamento al que pertenecen, mientras que la tablaDepartamento contiene los nombres de los departamentos de la empresa.

Existen empleados que tienen asignado un número de departamento que no se encuentra en la tabla Departamento (Gaspar). Igualmente, existen departamentos a los cuales no pertenece ningún empleado (Mercadeo). Esto servirá para presentar algunos ejemplos más adelante.

Combinación interna (INNER JOIN)

[editar]
Diagrama de Venn representando el Inner Join, entre las tablas A y B, de una sentencia SQL

Con esta operación cada registro en la tabla A es combinado con los correspondientes de la tabla B que satisfagan las condiciones que se especifiquen en el predicado delJOIN. Cualquier registro de la tabla A o de la tabla B que no tenga uno correspondiente en la otra tabla es excluido, y solo aparecerán los que tengan correspondencia en la otra tabla. Este es el tipo deJOIN más utilizado, por lo que es considerado el tipo de combinación predeterminado.

SQL:2003 especifica dos formas diferentes para expresar estas combinaciones. La primera, conocida comoexplícita, usa la palabraJOIN junto con las condiciones después de la palabra reservadaON. La segunda esimplícita y usa las comas para separar las tablas a combinar en la sentenciaFROM, y se usa la sentenciaWHERE para establecer las condiciones, la cual entonces es obligatoria para elINNER JOIN pues de lo contrario la sentencia sería unCROSS JOIN (ver más abajo).

Es necesario tener especial cuidado cuando se combinan columnas con valores nulosNULL, ya que el valor nulo no se combina con otro valor o con otro nulo, excepto cuando se le agregan predicados tales comoIS NULL oIS NOT NULL.

Como ejemplo, la siguiente consulta toma todos los registros de la tabla Empleado y encuentra todas las combinaciones en la tabla Departamento. La sentencia JOIN compara los valores en la columna IDDepartamento en ambas tablas. Cuando no existe esta correspondencia entre algunas combinaciones, estas no se muestran; es decir, que si el número de departamento de un empleado no coincide con los números de departamento de la tabla Departamento, no se mostrará el empleado con su respectivo departamento en la tabla resultante.

Las dos consultas siguientes son similares y se realizan de manera explícita (A) e implícita (B).

Ejemplo de la sentenciaINNER JOIN explícita:

SELECT*FROMempleadoINNERJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamento

Ejemplo de la sentenciaINNER JOIN implícita:

SELECT*FROMempleado,departamentoWHEREempleado.IDDepartamento=departamento.IDDepartamento

Resultados:

EmpleadoDepartamento
ApellidoIDDepartamentoNombreDepartamentoIDDepartamento
Zolano34Producción34
Jordán33Ingeniería33
Róbinson34Producción34
Steinberg33Ingeniería33
Andrade31Ventas31

El empleado Gaspar y el departamento de Mercadeo no son presentados en los resultados ya que ninguno de estos tiene registros correspondientes en la otra tabla. No existe un departamento con número 36 ni existe un empleado con número de departamento 35.

Theta Join

[editar]

A la combinación que utiliza comparaciones dentro del predicadoJOIN se le llamatheta-join. Se pueden hacer comparaciones de <, <=, =, <>, >= y >.

Ejemplo de combinación tipotheta:

SELECT*FROMempleadoINNERJOINdepartamentoONempleado.IDDepartamento<departamento.IDDepartamento

Las operacionesINNER JOIN puede ser clasificadas como de igualdad, naturales y cruzadas.

Equi-join

[editar]

Es una variedad deltheta-join que usa comparaciones de igualdad en el predicadoJOIN. Cuando se usan otros operadores de comparación no se puede clasificar en este rango.

Ejemplo de combinación de igualdad:

SELECT*FROMempleadoINNERJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamento

La tabla resultante presenta dos columnas llamadas IDDepartamento: una proveniente de la tabla Empleado y otra de la tabla Departamento.

SQL:2003 no tiene una sintaxis específica para esta clase de combinaciones.

Natural join

[editar]

Es una especialización de la combinación de igualdad, anteriormente mencionada, que se representa por el símbolo ⋈. En este caso se comparan todas las columnas que tengan el mismo nombre en ambas tablas. La tabla resultante contiene sólo una columna por cada par de columnas con el mismo nombre.

Ejemplo de combinación natural:

SELECT*FROMempleadoNATURALJOINdepartamento

El resultado es un poco diferente al del ejemplo de la tabla anterior, ya que esta vez la columna IDDepartamento se muestra sola una vez en la tabla resultante.

Empleado(campo común)Departamento
ApellidoIDDepartamentoNombreDepartamento
Zolano34Producción
Jordán33Ingeniería
Róbinson34Producción
Steinberg33Ingeniería
Andrade31Ventas

El uso de esta sentencia NATURAL puede producir resultados ambiguos y generar problemas si la base de datos cambia, porque al añadir, quitar o renombrar lascolumnas puede perder el sentido la sentencia; por esta razón es preferible expresar el predicado usando las otras expresiones nombradas anteriormente.

Combinación externa (OUTER JOIN)

[editar]

Mediante esta operación no se requiere que un registro en una tabla tenga un registro relacionado en la otra tabla. El registro es mantenido en la tabla combinada aunque no exista el correspondiente en la otra tabla.

Existen tres tipos de combinaciones externas, el Left Join, el Right Join y el Full Join, donde se toman todos los registros de la tabla de la izquierda, o todos los de la tabla derecha, o todos los registros respectivamente.

LEFT JOIN

[editar]
Diagrama de Venn representando el Left Join, entre las tablas A y B, de una sentencia SQL

El resultado de esta operación siempre contiene todos los registros de la tabla de la izquierda (la primera tabla que se menciona en la consulta), independientemente de si existe un registro correspondiente en la tabla de la derecha.

La sentenciaLEFT JOIN retorna la pareja de todos los valores de la tabla izquierda con los valores de la tabla de la derecha correspondientes, si los hay, o retorna un valor nuloNULL en los campos de la tabla derecha cuando no haya correspondencia.

A diferencia del resultado presentado en los ejemplos de combinación interna donde no se mostraba el empleado cuyo departamento no existía, en el siguiente ejemplo se presentarán los empleados con su respectivo departamento, y adicionalmente se presenta un empleado cuyo departamento no existe.

El empleado que no tiene departamento se encuentra en el área amarilla del diagrama de la derecha, mientras que los empleados con departamento están en el área anaranjada, en la intersección de A y B.

Ejemplo de left join para la combinación externa:

SELECT*FROMempleadoLEFTOUTERJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamento
EmpleadoDepartamento
ApellidoIDDepartamentoNombreDepartamentoIDDepartamento
Jordán33Ingeniería33
Andrade31Ventas31
Róbinson34Producción34
Zolano34Producción34
Gaspar36NULLNULL
Steinberg33Ingeniería33

LEFT JOIN excluyendo la intersección

[editar]
Diagrama de Venn representando el Left Join, entre las tablas A y B, agregando una condición donde las claves de B son nulas

Si se quieren mostrar solo los registros de la primera tabla que no tengan correspondientes en la segunda, se puede agregar la condición adecuada en la cláusulaWHERE. Esto nos dará los empleados que no estén asignados a ningún departamento, que en el diagrama de la derecha se representan en amarillo.

SELECT*FROMempleadoLEFTOUTERJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamentoWHEREdepartamento.IDDepartamentoISNULL
EmpleadoDepartamento
ApellidoIDDepartamentoNombreDepartamentoIDDepartamento
Gaspar36NULLNULL

RIGHT OUTER JOIN oRIGHT JOIN

[editar]
Diagrama de Venn representando el Right Join, entre las tablas A y B, de una sentencia SQL

Esta operación es una imagen refleja de la anterior; el resultado de esta operación siempre contiene todos los registros de la tabla de la derecha (la segunda tabla que se menciona en la consulta), independientemente de si existe o no un registro correspondiente en la tabla de la izquierda.

La sentenciaRIGHT OUTER JOIN retorna todos los valores de la tabla derecha con los valores de la tabla de la izquierda correspondientes, si los hay, o retorna un valor nuloNULL en los campos de la tabla izquierda cuando no haya correspondencia.

En el diagrama de la derecha, los departamentos que no tienen empleados están en el área verde mientras que los departamentos con empleados están en el área anaranjada, en la intersección de A y B.

Ejemplo de right join para la combinación externa:

SELECT*FROMempleadoRIGHTOUTERJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamento
EmpleadoDepartamento
ApellidoIDDepartamentoNombreDepartamentoIDDepartamento
Zolano34Producción34
Jordán33Ingeniería33
Róbinson34Producción34
Steinberg33Ingeniería33
Andrade31Ventas31
NULLNULLMercadeo35

En este caso el área de Mercadeo fue presentada en los resultados, aunque aún no hay empleados registrados en dicha área.

RIGHT JOIN excluyendo la intersección

[editar]
Diagrama de Venn representando el Right Join, entre las tablas A y B, agregando una condición donde las claves de A son nulas

Si se quieren mostrar solo los registros de la tabla de Departamento que no tengan correspondientes en la tabla de Empleado, se puede agregar la condición adecuada en la cláusulaWHERE. Esto nos dará los departamentos que no tengan asignados ningún empleado. En el diagrama de la derecha, esto se representa en verde.

SELECT*FROMempleadoRIGHTOUTERJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamentoWHEREempleado.IDDepartamentoISNULL
EmpleadoDepartamento
ApellidoIDDepartamentoNombreDepartamentoIDDepartamento
NULLNULLMercadeo35

Equivalencia entre LEFT JOIN y RIGHT JOIN

[editar]
Left Join equivalente al Right Join anterior

Hay una total equivalencia entre las sentencias que usan LEFT JOIN y las que usan RIGHT JOIN. Todo lo que se puede hacer con uno se puede hacer con el otro. Cambiando la perspectiva de cuál es la tabla izquierda y cuál es la tabla derecha, y teniendo cuidado con las condiciones, se puede hacer la sentencia equivalente.

Por ejemplo, hagamos el RIGHT JOIN anterior pero esta vez usando LEFT JOIN. En el RIGHT JOIN anterior se consideraba la tabla Empleado a la izquierda y la tabla de Departamento a la derecha. Para hacer un LEFT JOIN equivalente cambiamos de perspectiva y "volteamos" las tablas. Consideremos ahora la tabla de Departamento a la izquierda y la tabla de Empleado a la derecha. Podemos obtener exactamente el mismo resultado con la sentencia siguiente:

SELECT*FROMdepartamentoLEFTOUTERJOINempleadoONdepartamento.IDDepartamento=empleado.IDDepartamentoWHEREempleado.IDEmpleadoISNULL
DepartamentoEmpleado
NombreDepartamentoIDDepartamentoApellidoIDDepartamento
Mercadeo35NULLNULL

Combinación completa (FULL OUTER JOIN)

[editar]
Diagrama de Venn representando el Full Join, entre las tablas A y B, de una sentencia SQL

Esta operación presenta los resultados de tabla izquierda y tabla derecha aunque alguna no tengan correspondencia en la otra tabla. La tabla combinada contendrá, entonces, todos los registros de ambas tablas y presentará valores nulosNULLs para registros sin pareja.

En el diagrama de la derecha, el área anaranjada representa los empleados que están asociados a un departamento, el área amarilla son los empleados que no están en ningún departamento, y el área verde son los departamentos que no tienen empleados.

Ejemplo de combinación externa completa:

SELECT*FROMempleadoFULLOUTERJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamento
EmpleadoDepartamento
ApellidoIDDepartamentoNombreDepartamentoIDDepartamento
Zolano34Producción34
Jordán33Ingeniería33
Róbinson34Producción34
Gaspar36NULLNULL
Steinberg33Ingeniería33
Andrade31Ventas31
NULLNULLMercadeo35

Como se puede notar, en este caso se encuentra el empleado Gaspar con valor nulo en su área correspondiente, y se muestra además el departamento de Mercadeo con valor nulo en los empleados de esa área.

Algunos sistemas de bases de datos no soportan esta funcionalidad, pero esta puede ser emulada a través de las combinaciones de tabla izquierda, tabla derecha y de la sentencia de uniónunion.

El mismo ejemplo puede expresarse así:

SELECT*FROMempleadoLEFTJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamentoUNIONSELECT*FROMempleadoRIGHTJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamento

FULL JOIN excluyendo la intersección

[editar]
Diagrama de Venn representando el Full Join, entre las tablas A y B, agregando condiciones donde la clave de A o la de B son nulas

Si se quieren mostrar solo los registros de las tablas que no tengan correspondencia en la otra, se pueden agregar las condiciones adecuadas en la cláusulaWHERE.

En el diagrama de la derecha, el área amarilla representa los empleados que no están asignados a ningún departamento, mientras que el área verde representa los departamentos que no tienen empleados.

SELECT*FROMempleadoFULLOUTERJOINdepartamentoONempleado.IDDepartamento=departamento.IDDepartamentoWHERE(empleado.IDDepartamentoISNULL)OR(departamento.IDDepartamentoisNULL)
EmpleadoDepartamento
ApellidoIDDepartamentoNombreDepartamentoIDDepartamento
Gaspar36NULLNULL
NULLNULLMercadeo35

Cruzada (Cross join)

[editar]
Representación comoproducto cartesiano del Cross Join, entre las tablas A y B, de una sentencia SQL

El CROSS JOIN presenta elproducto cartesiano de los registros de las dos tablas. La tabla resultante tendrá todos los registros de la tabla izquierda combinados con cada uno de los registros de la tabla derecha.

El código SQL para realizar este producto cartesiano enuncia las tablas que serán combinadas, pero no incluye algún predicado que filtre el resultado.

Ejemplo de combinación cruzada explícita:

SELECT*FROMempleadoCROSSJOINdepartamento

Ejemplo de combinación cruzada implícita:

SELECT*FROMempleado,departamento;
EmpleadoDepartamento
ApellidoIDDepartamentoNombreDepartamentoIDDepartamento
Andrade31Ventas31
Jordán33Ventas31
Steinberg33Ventas31
Zolano34Ventas31
Róbinson34Ventas31
Gaspar36Ventas31
Andrade31Ingeniería33
Jordán33Ingeniería33
Steinberg33Ingeniería33
Zolano34Ingeniería33
Róbinson34Ingeniería33
Gaspar36Ingeniería33
Andrade31Producción34
Jordán33Producción34
Steinberg33Producción34
Zolano34Producción34
Róbinson34Producción34
Gaspar36Producción34
Andrade31Mercadeo35
Jordán33Mercadeo35
Steinberg33Mercadeo35
Zolano34Mercadeo35
Róbinson34Mercadeo35
Gaspar36Mercadeo35

Esta clase de combinaciones son usadas pocas veces; generalmente se les agregan condiciones de filtrado con la sentenciaWHERE para hallar resultados específicos.

Implementación

[editar]

La implementación eficiente de combinaciones ha sido un objetivo de mucho trabajo en los sistemas de bases de datos, pues aunque sean internas o externas, son muy comunes y difíciles de ejecutar eficientemente. La combinación interna de tablas se puede hacer con propiedadconmutativa yasociativa, así que el usuario sólo crea la consulta y el sistema de base de datos determina la manera más eficiente de realizar la operación. Esta decisión la toma eloptimizador de consultas, que tiene en cuenta dos puntos importantes:

El orden de las combinaciones
como las combinaciones son conmutativas, el orden en el cual son combinadas las tablas no modifica el resultado final de la consulta. En cambio, sí tiene un gran impacto sobre el costo de la operación, de manera que elegir el mejor orden de combinaciones es muy importante.
El método de la combinación
dadas dos tablas y una condición de combinación, existen unos cuantosalgoritmos que devuelven el resultado de la combinación. Cuál algoritmo es el más eficiente dependerá de los tamaños de las tablas de entrada, la cantidad defilas de cada una que satisfacen la condición de combinación y las operaciones requeridas por el resto de la consulta.

Los diferentesalgoritmos tratan de forma diferente a las entradas. A las entradas de una combinación se las llama respectivamente "operandoexterno(outer)" y "operandointerno(inner)", o bien simplementeizquierdo yderecho. En el caso de bucles anidados, por ejemplo, la relación interna será completamente recorrida por cada fila de la relación externa.

Los planes de ejecución que incluyen combinaciones pueden clasificarse en:

Profundo a la izquierda
El operando interno de cada combinación del plan es una tabla base.
Profundo a la derecha
El operando externo de cada combinación del plan es una tabla base.
Denso
Ambas entradas son combinaciones.

Estos nombres derivan de la apariencia de la representación gráfica del plan de ejecución como unárbol, con la relación externa a la izquierda y la interna a la derecha (por convención).

Algoritmos de combinación

[editar]

Existen tres algoritmos fundamentales para ejecutar una operación de combinación.

Bucles anidados

[editar]

Éste es el más simple de los algoritmos de combinación. Por cadatupla de la relación externa, se recorrecompletamente la relación interna, y toda tupla que verifique la condición de combinación se añade al resultado. El algoritmo puede ser fácilmente generalizado para cualquier número de relaciones.

Pseudocódigo para la combinación de las relacionesR{\displaystyle R} andS{\displaystyle S}:

  Por cada tupla en R, llamada r:     Por cada tupla en S, llamada s:        Si la tupla <r,s> satisface la condición de combinación           Entonces agregar la tupla <r,s> a la salida

La complejidad computacional del algoritmo es deO(|R||S|){\displaystyle O(|R||S|)} operaciones de entrada/salida, donde|R|{\displaystyle |R|} y|S|{\displaystyle |S|} son la cantidad de tuplas enR{\displaystyle R} yS{\displaystyle S} respectivamente.

Naturalmente, este algoritmo tiene un desempeño pobre si alguna de las relaciones es muy grande. El desempeño puede mejorarse si la relación interna tiene uníndice sobre las columnas del predicado de combinación.

Existe una variación del algoritmo de bucles anidados, llamadabucles anidados en bloque.Sea|R|<|S|{\displaystyle |R|<|S|}. En lugar de leer las dos relaciones tupla por tupla, se lee la relaciónR{\displaystyle R} en bloques, llenando toda la memoria disponible, excepto dos páginas. Por cada bloque deR{\displaystyle R} se realiza una iteración sobreS{\displaystyle S}, leyendo una página por vez, y por cada página leída deS{\displaystyle S}, la tupla de la página es comparada con las del bloque deR{\displaystyle R}, y cada par de tuplas que satisfacen la condición de combinación se agrega a la página de salida.

El algoritmo debucles anidados en bloque tiene una complejidad computacional deO(PrPsM){\displaystyle O({\frac {P_{r}P_{s}}{M}})} operaciones de entrada/salida, dondeM{\displaystyle M} es el número de páginas de memoria disponibles yPr{\displaystyle P_{r}} yPs{\displaystyle P_{s}} son el tamaño en páginas deR{\displaystyle R} y deS{\displaystyle S} respectivamente. Notar que la complejidad computacional es deO(Pr+Ps){\displaystyle O(P_{r}+P_{s})} operaciones de entrada/salida siR{\displaystyle R} cabe en la memoria disponible.

Combinación por fusión

[editar]

Si ambas relaciones están ordenadas por los atributos de combinación, la operación es trivial:

  1. Por cada tupla de la relación externa,
    1. Se toma elgrupo de tuplas actual de la relación interna; un grupo está formado por un conjunto de tuplas contiguas con el mismo valor en el atributo de combinación.
    2. Por cada tupla del grupo interno actual que satisfaga la condición de combinación, se agrega una tupla al resultado. Una vez agotado el grupo interno, ambas búsquedas, la interna y la externa, pueden avanzar al siguiente grupo.

Por esta razón muchosoptimizadores guardan pista del ordenamiento en los nodos del plan (si uno o ambos operandos ya están ordenados en función del atributo de combinación, no hace falta otro ordenamiento. De lo contrario, elsistema de gestión de base de datos deberá realizarlo, generalmente utilizando unordenamiento externo para evitar consumir demasiada memoria.

Combinación Hash

[editar]

Este algoritmo puede ser utilizado para combinaciones "equi-join". El acceso a las tablas a ser combinadas se realiza construyendotablas hash sobre los atributos de combinación. La búsqueda entabla hash es mucho más rápida que a través de árboles de índice, pero solo puede realizarse una búsqueda por la condición de igualdad.

Optimización de la combinación

[editar]

Semi-combinación

[editar]

Es una optimización técnica para las combinaciones en bases de datos distribuidas. El predicadoJOIN es aplicado en diferentes fases, comenzando con la más temprana. Esto puede reducir el tamaño de los resultados inmediatos que deben ser intercambiados con nodos remotos, así reduce el tráfico de red entre nodos, esto puede mejorarse con un filtro Bloom.

Véase también

[editar]

Enlaces externos

[editar]
Control de autoridades

Obtenido de «https://es.wikipedia.org/w/index.php?title=Sentencia_JOIN_en_SQL&oldid=168919551»
Categoría:
Categorías ocultas:

[8]ページ先頭

©2009-2026 Movatter.jp