JOIN genera una tabla nueva al combinar columnas de una o varias tablas mediante valores comunes entre ellas. Es una operación habitual en las bases de datos con soporte para SQL, que se corresponde con la operación join del álgebra relacional. El caso especial de unir una tabla consigo misma suele denominarse “autounión”.
Sintaxis
ON y las columnas de la cláusula USING se denominan “claves de JOIN”. A menos que se indique lo contrario, un JOIN produce un producto cartesiano de las filas con “claves de JOIN” coincidentes, lo que puede generar resultados con muchas más filas que las tablas de origen.
Tipos de JOIN compatibles
| Tipo | Descripción |
|---|---|
INNER JOIN | solo se devuelven las filas coincidentes. |
LEFT OUTER JOIN | además de las filas coincidentes, se devuelven las filas no coincidentes de la tabla izquierda. |
RIGHT OUTER JOIN | además de las filas coincidentes, se devuelven las filas no coincidentes de la tabla derecha. |
FULL OUTER JOIN | además de las filas coincidentes, se devuelven las filas no coincidentes de ambas tablas. |
CROSS JOIN | produce el producto cartesiano de las tablas completas; no se especifican “join keys”. |
NATURAL JOIN | une automáticamente todas las columnas con el mismo nombre en ambas tablas; cada columna común aparece una sola vez en el resultado. Admite las variantes INNER (predeterminada), LEFT, RIGHT y FULL. Equivale a JOIN ... USING (col1, col2, ...), donde la lista de columnas se obtiene automáticamente. |
JOINsin especificar un tipo implicaINNER.- La palabra clave
OUTERpuede omitirse sin problema. - Una sintaxis alternativa para
CROSS JOINconsiste en especificar varias tablas en la cláusulaFROM, separadas por comas. - Si no hay columnas coincidentes para un
NATURAL JOIN, funciona como unCROSS JOIN.
| Tipo | Descripción |
|---|---|
LEFT SEMI JOIN, RIGHT SEMI JOIN | Una lista de permitidos sobre “join keys”, sin generar un producto cartesiano. |
LEFT ANTI JOIN, RIGHT ANTI JOIN | Una lista de bloqueados sobre “join keys”, sin generar un producto cartesiano. |
LEFT ANY JOIN, RIGHT ANY JOIN, INNER ANY JOIN | Desactiva parcial (para el lado opuesto de LEFT y RIGHT) o completamente (para INNER y FULL) el producto cartesiano de los tipos estándar de JOIN. |
ASOF JOIN, LEFT ASOF JOIN | Une secuencias con una coincidencia no exacta. El uso de ASOF JOIN se describe a continuación. |
PASTE JOIN | Realiza una concatenación horizontal de dos tablas. |
Cuando join_algorithm se establece en
partial_merge, RIGHT JOIN y FULL JOIN solo son compatibles con strictness ALL (SEMI, ANTI, ANY y ASOF no son compatibles).Configuración
join_default_strictness.
El comportamiento del servidor ClickHouse en las operaciones ANY JOIN depende de la configuración any_join_distinct_right_table_keys.
Véase también
join_algorithmjoin_any_take_last_rowjoin_use_nullspartial_merge_join_rows_in_right_blocksjoin_on_disk_max_files_to_mergeany_join_distinct_right_table_keys
cross_to_inner_join_rewrite para definir el comportamiento cuando ClickHouse no consigue reescribir un CROSS JOIN como un INNER JOIN. El valor predeterminado es 1, lo que permite que el JOIN continúe, aunque será más lento. Establezca cross_to_inner_join_rewrite en 0 si desea que se genere un error, y en 2 si no quiere ejecutar los cross joins, sino forzar la reescritura de todos los comma/cross joins. Si la reescritura falla cuando el valor es 2, recibirá un mensaje de error que indica “Please, try to simplify WHERE section”.
Condiciones de la sección ON
ON puede contener varias condiciones combinadas con los operadores AND y OR. Las condiciones que especifican claves de JOIN deben:
- hacer referencia tanto a la tabla izquierda como a la derecha
- usar el operador de igualdad
JOIN. Tenga en cuenta que, si las mismas condiciones se colocan en una sección WHERE y no se cumplen, las filas siempre se excluyen del resultado.
El operador OR dentro de la cláusula ON funciona con el algoritmo hash join: para cada argumento OR con claves de JOIN para JOIN, se crea una tabla hash independiente, por lo que el consumo de memoria y el tiempo de ejecución de la consulta aumentan linealmente a medida que crece el número de expresiones OR en la cláusula ON.
Si una condición hace referencia a columnas de distintas tablas, por ahora solo se admite el operador de igualdad (
=).table_1 y table_2:
table_2:
Query
C y la columna de texto vacía. Se incluye en el resultado porque se usa un join de tipo OUTER.
Response
INNER y múltiples condiciones:
Query
Response
INNER y una condición con OR:
Query
Response
INNER y condiciones con OR y AND:
De forma predeterminada, se admiten condiciones de desigualdad siempre que usen columnas de la misma tabla.
Por ejemplo,
t1.a = t2.key AND t1.b > 0 AND t2.b > t2.c, porque t1.b > 0 usa únicamente columnas de t1 y t2.b > t2.c usa únicamente columnas de t2.
Sin embargo, puede probar la compatibilidad experimental con condiciones como t1.a = t2.key AND t1.b > t2.key; consulte la sección siguiente para obtener más información.Query
Response
JOIN con condiciones de desigualdad para columnas de diferentes tablas
ALL/ANY/SEMI/ANTI INNER/LEFT/RIGHT/FULL JOIN con condiciones de desigualdad además de las condiciones de igualdad. Las condiciones de desigualdad solo se admiten con los algoritmos de join hash y grace_hash. Las condiciones de desigualdad no son compatibles con join_use_nulls.
Ejemplo
Tabla t1:
t2
Valores NULL en las claves de JOIN
NULL no es igual a ningún valor, incluido él mismo. Esto significa que, si una clave de JOIN tiene un valor NULL en una tabla, no coincidirá con un valor NULL de la otra tabla.
Ejemplo
Tabla A:
B:
Charlie de la tabla A y la fila con puntuación 88 de la tabla B no aparecen en el resultado debido al valor NULL en la clave del JOIN.
Si quiere hacer coincidir valores NULL, use la función isNotDistinctFrom para comparar las claves del JOIN.
Uso de ASOF JOIN
ASOF JOIN es útil cuando necesitas unir registros que no tienen una correspondencia exacta.
Este algoritmo de JOIN requiere una columna especial en las tablas. Esta columna:
- Debe contener una secuencia ordenada.
- Puede ser de uno de los siguientes types: Int, UInt, Float, Date, DateTime, Decimal.
- En el caso del algoritmo de join
hash, no puede ser la única columna de la cláusulaJOIN.
ASOF JOIN ... ON:
SELECT count() FROM table_1 ASOF LEFT JOIN table_2 ON table_1.a == table_2.b AND table_2.t <= table_1.t.
Condiciones admitidas para la coincidencia más próxima: >, >=, <, <=.
Sintaxis de ASOF JOIN ... USING:
ASOF JOIN usa equi_columnX para unir por igualdad y asof_column para unir por la coincidencia más cercana con la condición table_1.asof_column >= table_2.asof_column. La columna asof_column siempre es la última de la cláusula USING.
Por ejemplo, considere las siguientes tablas:
ASOF JOIN puede tomar el timestamp de un evento de usuario de table_1 y encontrar un evento en table_2 cuyo timestamp sea el más cercano al del evento de table_1 que corresponda a la condición de coincidencia más próxima. Si existen, los valores de timestamp iguales son los más cercanos. Aquí, la columna user_id puede usarse para hacer el JOIN por igualdad y la columna ev_time para hacer el JOIN por coincidencia más próxima. En nuestro ejemplo, event_1_1 puede unirse con event_2_1 y event_1_2 puede unirse con event_2_3, pero event_2_2 no puede unirse.
ASOF JOIN solo es compatible con los algoritmos de join hash y full_sorting_merge.
No es compatible con el motor de tabla Join.Uso de PASTE JOIN
PASTE JOIN es una tabla que contiene todas las columnas de la subconsulta izquierda, seguidas de todas las columnas de la subconsulta derecha.
Las filas se emparejan según su posición en las tablas originales (el orden de las filas debe estar definido).
Si las subconsultas devuelven un número distinto de filas, las filas sobrantes se descartan.
Ejemplo:
JOIN distribuido
- Al usar un
JOINnormal, la consulta se envía a los servidores remotos. Las subconsultas se ejecutan en cada uno de ellos para crear la tabla del lado derecho, y el JOIN se realiza con esa tabla. En otras palabras, la tabla del lado derecho se forma por separado en cada servidor. - Al usar
GLOBAL ... JOIN, primero el servidor solicitante ejecuta una subconsulta para calcular uno de los lados del JOIN y recopila el resultado en una tabla temporal. Esta tabla temporal se envía luego a cada servidor remoto, y las consultas se ejecutan en ellos usando los datos temporales transmitidos. En los JOINLEFTeINNER, la tabla del lado derecho se calcula como la subconsulta. En los JOINRIGHT, en cambio, se calcula la tabla del lado izquierdo, ya que la tabla del lado derecho es la que se conserva y debe leerse desde los segmentos.
GLOBAL. Para obtener más información, consulte la sección Subconsultas distribuidas.
Conversión implícita de tipos
INNER JOIN, LEFT JOIN, RIGHT JOIN y FULL JOIN admiten la conversión implícita de tipos para las “claves de JOIN”. Sin embargo, la consulta no puede ejecutarse si las claves de JOIN de las tablas izquierda y derecha no pueden convertirse a un único tipo (por ejemplo, no existe ningún tipo de dato que pueda contener todos los valores de UInt64 e Int64, o de String e Int32).
Ejemplo
Considere la tabla t_1:
t_2:
Recomendaciones de uso
Procesamiento de celdas vacías o NULL
JOIN son campos Nullable, las filas en las que al menos una de las claves tiene el valor NULL no se unen.
Sintaxis
USING deben tener los mismos nombres en ambas subconsultas, y las demás columnas deben llamarse de forma diferente. Puede usar alias para cambiar los nombres de las columnas en las subconsultas.
La cláusula USING especifica una o varias columnas para el join, lo que establece la igualdad entre ellas. La lista de columnas se indica sin paréntesis. No se admiten condiciones de join más complejas.
Limitaciones de sintaxis
JOIN en una sola consulta SELECT:
- Seleccionar todas las columnas con
*solo está disponible cuando se unen tablas, no subconsultas. - La cláusula
PREWHEREno está disponible. - La cláusula
USINGno está disponible.
ON, WHERE y GROUP BY:
- No se pueden usar expresiones arbitrarias en las cláusulas
ON,WHEREyGROUP BY, pero puede definir una expresión en una cláusulaSELECTy luego usarla en estas cláusulas mediante un alias.
Rendimiento
JOIN, no se optimiza el orden de ejecución con respecto a otras etapas de la consulta. El JOIN (una búsqueda en la tabla de la derecha) se ejecuta antes del filtrado en WHERE y antes de la agregación.
Cada vez que se ejecuta una consulta con el mismo JOIN, la subconsulta se vuelve a ejecutar porque el resultado no se almacena en caché. Para evitarlo, use el motor de tabla especial Join, que es un array preparado para operaciones de join y que siempre está en RAM.
En algunos casos, es más eficiente usar IN en lugar de JOIN.
Si necesita un JOIN para unir tablas de dimensiones (tablas relativamente pequeñas que contienen propiedades de dimensión, como nombres de campañas publicitarias), puede que JOIN no sea la opción más adecuada, ya que se vuelve a acceder a la tabla de la derecha en cada consulta. Para esos casos, existe la funcionalidad de “diccionarios”, que debería usar en lugar de JOIN. Para obtener más información, consulte la sección Diccionarios.
Limitaciones de memoria
join_algorithm = 'auto' está habilitado, al superar cierto umbral de consumo de memoria, ClickHouse cambia al algoritmo merge join. Para ver la descripción de los algoritmos JOIN, consulte la configuración join_algorithm.
Si necesita restringir el consumo de memoria de la operación JOIN, use la siguiente configuración:
- max_rows_in_join — Limita el número de filas de la tabla hash.
- max_bytes_in_join — Limita el tamaño de la tabla hash.
Ejemplos
- Blog: ClickHouse: un DBMS rapidísimo con soporte completo para SQL JOIN - Parte 1
- Blog: ClickHouse: un DBMS rapidísimo con soporte completo para SQL JOIN - Por dentro - Parte 2
- Blog: ClickHouse: un DBMS rapidísimo con soporte completo para SQL JOIN - Por dentro - Parte 3
- Blog: ClickHouse: un DBMS rapidísimo con soporte completo para SQL JOIN - Por dentro - Parte 4