Pular para o conteúdo principal
A cláusula JOIN produz uma nova tabela ao combinar colunas de uma ou mais tabelas com base em valores em comum entre elas. É uma operação comum em bancos de dados com suporte a SQL, correspondente à operação de junção da álgebra relacional. O caso especial de uma junção de uma tabela com ela mesma costuma ser chamado de “self-join”. Sintaxe
Expressões da cláusula ON e colunas da cláusula USING são chamadas de “chaves de junção”. Salvo indicação em contrário, um JOIN produz um produto cartesiano entre linhas com “chaves de junção” correspondentes, o que pode gerar resultados com muito mais linhas do que as tabelas de origem.

Tipos de JOIN suportados

Todos os tipos padrão de SQL JOIN são suportados:
  • JOIN sem tipo especificado implica INNER.
  • A palavra-chave OUTER pode ser omitida com segurança.
  • Uma sintaxe alternativa para CROSS JOIN é especificar várias tabelas na cláusula FROM, separadas por vírgulas.
  • Se não houver colunas correspondentes para um NATURAL JOIN, ele funciona como um CROSS JOIN.
Os tipos adicionais de junção disponíveis no ClickHouse são:
Quando join_algorithm está definido como partial_merge, RIGHT JOIN e FULL JOIN são suportados apenas com a strictness ALL (SEMI, ANTI, ANY e ASOF não são suportados).

Configurações

O tipo de junção padrão pode ser substituído usando a configuração join_default_strictness. O comportamento do servidor do ClickHouse para operações ANY JOIN depende da configuração any_join_distinct_right_table_keys. Veja também Use a configuração cross_to_inner_join_rewrite para definir o comportamento quando o ClickHouse não consegue reescrever um CROSS JOIN como um INNER JOIN. O valor padrão é 1, o que permite que a junção continue, mas ela será mais lenta. Defina cross_to_inner_join_rewrite como 0 se quiser que um erro seja gerado e como 2 para não executar os CROSS JOIN, mas sim forçar a reescrita de todas as junções com vírgula ou CROSS JOIN. Se a reescrita falhar quando o valor for 2, você receberá uma mensagem de erro informando “Please, try to simplify WHERE section”.

Condições da seção ON

Uma seção ON pode conter várias condições combinadas com os operadores AND e OR. As condições que especificam chaves de junção devem:
  • referenciar as tabelas da esquerda e da direita
  • usar o operador de igualdade
Outras condições podem usar outros operadores lógicos, mas devem referenciar ou a tabela da esquerda ou a da direita de uma consulta. As linhas são combinadas se toda a condição composta for atendida. Se as condições não forem atendidas, as linhas ainda poderão ser incluídas no resultado, dependendo do tipo de JOIN. Observe que, se as mesmas condições forem colocadas em uma seção WHERE e não forem atendidas, as linhas sempre serão filtradas do resultado. O operador OR dentro da cláusula ON funciona com o algoritmo de hash junção — para cada argumento OR com chaves de junção para JOIN, é criada uma tabela hash separada; assim, o consumo de memória e o tempo de execução da consulta aumentam linearmente à medida que cresce o número de expressões OR na cláusula ON.
Se uma condição referencia colunas de tabelas diferentes, por enquanto só há suporte ao operador de igualdade (=).
Exemplo Considere table_1 e table_2:
Consulta com uma condição na chave de junção e uma condição adicional para table_2:
Query
Observe que o resultado contém a linha com o nome C e a coluna de texto vazia. Ela foi incluída no resultado porque foi usada uma junção do tipo OUTER.
Response
Consulta com junção do tipo INNER e múltiplas condições:
Query
Response
Consulta com junção do tipo INNER e condição com OR:
Query
Response
Consulta com INNER como tipo de junção e condições com OR e AND:
Por padrão, condições de desigualdade são aceitas, desde que usem colunas da mesma tabela. Por exemplo, t1.a = t2.key AND t1.b > 0 AND t2.b > t2.c, porque t1.b > 0 usa apenas colunas de t1 e t2.b > t2.c usa apenas colunas de t2. No entanto, você pode testar o suporte experimental para condições como t1.a = t2.key AND t1.b > t2.key; consulte a seção abaixo para mais detalhes.
Query
Response

Junção com condições de desigualdade para colunas de tabelas diferentes

Atualmente, o ClickHouse oferece suporte a ALL/ANY/SEMI/ANTI INNER/LEFT/RIGHT/FULL JOIN com condições de desigualdade, além das condições de igualdade. As condições de desigualdade são compatíveis apenas com os algoritmos de junção hash e grace_hash. As condições de desigualdade não são compatíveis com join_use_nulls. Exemplo Tabela t1:
Tabela t2

Valores NULL nas chaves de JOIN

NULL não é igual a nenhum valor, nem a si mesmo. Isso significa que, se uma chave de JOIN tiver um valor NULL em uma tabela, ela não corresponderá a um valor NULL na outra tabela. Exemplo Tabela A:
Tabela B:
Observe que a linha com Charlie da tabela A e a linha com pontuação 88 da tabela B não aparecem no resultado por causa do valor NULL na chave de JOIN. Caso você queira fazer a correspondência de valores NULL, use a função isNotDistinctFrom para comparar as chaves de JOIN.

Uso do ASOF JOIN

ASOF JOIN é útil quando você precisa combinar registros que não têm correspondência exata. Este algoritmo de junção exige uma coluna especial nas tabelas. Essa coluna:
  • Deve conter uma sequência ordenada.
  • Pode ser de um dos seguintes tipos: Int, UInt, Float, Date, DateTime, Decimal.
  • No algoritmo de junção hash, ela não pode ser a única coluna na cláusula JOIN.
Sintaxe ASOF JOIN ... ON:
Você pode usar qualquer número de condições de igualdade e exatamente uma condição de correspondência mais próxima. Por exemplo, SELECT count() FROM table_1 ASOF LEFT JOIN table_2 ON table_1.a == table_2.b AND table_2.t <= table_1.t. Condições aceitas para a correspondência mais próxima: >, >=, <, <=. Sintaxe de ASOF JOIN ... USING:
ASOF JOIN usa equi_columnX para fazer a junção por igualdade e asof_column para fazer a junção pela correspondência mais próxima com a condição table_1.asof_column >= table_2.asof_column. A coluna asof_column é sempre a última na cláusula USING. Por exemplo, considere as tabelas a seguir:
ASOF JOIN pode usar o timestamp de um evento de usuário de table_1 e encontrar um evento em table_2 cujo timestamp seja o mais próximo do timestamp do evento de table_1, de acordo com a condição de correspondência mais próxima. Valores de timestamp iguais são considerados os mais próximos, quando disponíveis. Aqui, a coluna user_id pode ser usada na junção por igualdade, e a coluna ev_time pode ser usada na junção pela correspondência mais próxima. No nosso exemplo, event_1_1 pode ser unido a event_2_1 e event_1_2 pode ser unido a event_2_3, mas event_2_2 não pode ser unido.
ASOF JOIN é compatível apenas com os algoritmos de junção hash e full_sorting_merge. Não é compatível com o mecanismo de tabela Join.

Uso do PASTE JOIN

O resultado de PASTE JOIN é uma tabela que contém todas as colunas da subconsulta à esquerda, seguidas de todas as colunas da subconsulta à direita. As linhas são associadas com base em suas posições nas tabelas originais (a ordem das linhas deve estar definida). Se as subconsultas retornarem números diferentes de linhas, as linhas excedentes serão descartadas. Exemplo:
Nota: neste caso, o resultado pode não ser determinístico se a leitura ocorrer em paralelo. Por exemplo:

JOIN distribuído

Há duas maneiras de executar um JOIN que envolve tabelas distribuídas:
  • Ao usar um JOIN normal, a consulta é enviada aos servidores remotos. As subconsultas são executadas em cada um deles para montar a tabela da direita, e a junção é realizada com essa tabela. Em outras palavras, a tabela da direita é formada separadamente em cada servidor.
  • Ao usar GLOBAL ... JOIN, primeiro o servidor solicitante executa uma subconsulta para calcular um dos lados da junção e armazena o resultado em uma tabela temporária. Essa tabela temporária é então enviada a cada servidor remoto, e as consultas são executadas neles usando os dados temporários transmitidos. Para junções LEFT e INNER, a tabela da direita é calculada pela subconsulta. Para junções RIGHT, a tabela da esquerda é calculada, já que a tabela da direita é a preservada e deve ser lida dos shards.
Tenha cuidado ao usar GLOBAL. Para mais informações, consulte a seção Subconsultas distribuídas.

Conversão implícita de tipos

Consultas INNER JOIN, LEFT JOIN, RIGHT JOIN e FULL JOIN oferecem suporte à conversão implícita de tipos para as “chaves de junção”. No entanto, a consulta não pode ser executada se as chaves de junção das tabelas à esquerda e à direita não puderem ser convertidas para um único tipo (por exemplo, não há nenhum tipo de dado que possa comportar todos os valores de UInt64 e Int64, ou de String e Int32). Exemplo Considere a tabela t_1:
e a tabela t_2:
A consulta
retorna o conjunto:

Recomendações de uso

Processamento de células vazias ou NULL

Ao fazer JOIN entre tabelas, podem surgir células vazias. A configuração join_use_nulls define como o ClickHouse preenche essas células. Se as chaves de JOIN forem campos Nullable, as linhas em que pelo menos uma das chaves tem o valor NULL não são unidas.

Sintaxe

As colunas especificadas em USING devem ter os mesmos nomes em ambas as subconsultas, e as demais colunas devem ter nomes diferentes. Você pode usar aliases para alterar os nomes das colunas nas subconsultas. A cláusula USING especifica uma ou mais colunas para unir, estabelecendo a igualdade entre essas colunas. A lista de colunas é definida sem parênteses. Condições de junção mais complexas não são suportadas.

Limitações de sintaxe

Para várias cláusulas JOIN em uma única consulta SELECT:
  • Selecionar todas as colunas com * só é possível quando há junção entre tabelas, e não subconsultas.
  • A cláusula PREWHERE não está disponível.
  • A cláusula USING não está disponível.
Para as cláusulas ON, WHERE e GROUP BY:
  • Não é possível usar expressões arbitrárias nas cláusulas ON, WHERE e GROUP BY, mas você pode definir uma expressão em uma cláusula SELECT e depois usá-la nessas cláusulas por meio de um alias.

Desempenho

Ao executar um JOIN, não há otimização da ordem de execução em relação às outras etapas da consulta. A junção (uma busca na tabela da direita) é executada antes da filtragem em WHERE e antes da agregação. Sempre que uma consulta é executada com o mesmo JOIN, a subconsulta é executada novamente, porque o resultado não fica em cache. Para evitar isso, use o mecanismo de tabela especial Join, que é um array pré-preparado para junções e permanece sempre na RAM. Em alguns casos, é mais eficiente usar IN em vez de JOIN. Se você precisar de um JOIN para fazer junção com tabelas de dimensão (tabelas relativamente pequenas que contêm propriedades de dimensão, como nomes de campanhas publicitárias), um JOIN pode não ser muito prático, já que a tabela da direita é acessada novamente a cada consulta. Nesses casos, existe o recurso “dicionários”, que você deve usar em vez de JOIN. Para mais informações, consulte a seção Dicionários.

Limitações de memória

Por padrão, o ClickHouse usa o algoritmo hash junção. O ClickHouse usa a right_table e cria uma tabela hash para ela na RAM. Se join_algorithm = 'auto' estiver habilitado, após determinado limite de consumo de memória, o ClickHouse passa a usar o algoritmo merge de junção. Para obter uma descrição dos algoritmos de junção, consulte a configuração join_algorithm. Se você precisar restringir o consumo de memória da operação de junção JOIN, use as seguintes configurações: Quando qualquer um desses limites é atingido, o ClickHouse age conforme instruído pela configuração join_overflow_mode.

Exemplos

Exemplo:
Última modificação em 10 de junho de 2026