Pular para o conteúdo principal

JoinTransformer

Visão geral​

Converte nós Join do Tableau em instruções SQL JOIN. Combina dois conjuntos de dados de entrada com base nas condições de junção, com suporte a múltiplos tipos de junção (INNER, LEFT, RIGHT, FULL e ANTI).

Tipo de nó: .v1.SimpleJoin / .v2018_2_3.SuperJoin Saída: SQL SELECT com JOIN

Recursos​

  • Tipos de junção: INNER, LEFT, RIGHT, FULL, LEFT ANTI, RIGHT ANTI
  • Múltiplas condições de junção (lógica AND)
  • Comparações de igualdade (==)
  • Tratamento de nomes de colunas duplicados com sufixos
  • Aliases de tabelas para maior clareza

Exemplo de nó Tableau​

Exemplo 1: junção interna em múltiplas colunas​

Entrada (formato Tableau)​

{
"id": "7bf017f8-2d70-411f-8af2-a831301b1c66",
"name": "Join Sales by Period",
"node_type": ".v2018_2_3.SuperJoin",
"base_type": "superNode",
"actionNode": {
"nodeType": ".v1.SimpleJoin",
"joinType": "inner",
"conditions": [
{
"comparator": "==",
"leftExpression": "[Year]",
"rightExpression": "[Year]"
},
{
"comparator": "==",
"leftExpression": "[Month]",
"rightExpression": "[Month]"
}
]
}
}

Esquemas de entrada​

Entrada esquerda (dados de vendas):

[
{"name": "year", "type": "integer"},
{"name": "month", "type": "integer"},
{"name": "region", "type": "string"},
{"name": "sales_amount", "type": "real"},
{"name": "customer_name", "type": "string"}
]

Entrada direita (dados de metas):

[
{"name": "year", "type": "integer"},
{"name": "month", "type": "integer"},
{"name": "target_amount", "type": "real"}
]

SQL gerado​

SELECT
a.region,
a.sales_amount,
a.customer_name,
a.month,
a.year,
b.target_amount,
b.ano AS year_1,
b.mes AS month_1
FROM sales_data_V0S12 AS a
INNER JOIN targets_V0S15 AS b
ON a.year = b.year AND a.month = b.month

Esquema de saída​

{
"region": "string",
"sales_amount": "real",
"customer_name": "string",
"month": "integer",
"year": "integer",
"target_amount": "real",
"year_1": "integer",
"month_1": "integer"
}

Exemplo 2: junção à esquerda (manter todas as linhas da esquerda)​

Entrada (formato Tableau)​

{
"id": "8c9d0e1f-2a3b-4c5d-6e7f-8a9b0c1d2e3f",
"name": "Join Customers with Orders",
"node_type": ".v1.SimpleJoin",
"actionNode": {
"joinType": "left",
"conditions": [
{
"comparator": "==",
"leftExpression": "[Customer ID]",
"rightExpression": "[Customer ID]"
}
]
}
}

SQL gerado​

SELECT
a.customer_id,
a.customer_name,
a.email,
b.order_id,
b.order_date,
b.order_amount,
b.customer_id AS customer_id_1
FROM customers_V0S5 AS a
LEFT JOIN orders_V0S8 AS b
ON a.customer_id = b.customer_id

Exemplo 3: junção à direita​

Entrada (formato Tableau)​

{
"id": "9d0e1f2a-3b4c-5d6e-7f8a-9b0c1d2e3f4a",
"name": "Right Join Products",
"node_type": ".v1.SimpleJoin",
"actionNode": {
"joinType": "right",
"conditions": [
{
"comparator": "==",
"leftExpression": "[Product Code]",
"rightExpression": "[Product Code]"
}
]
}
}

SQL gerado​

SELECT
a.product_code,
a.sales_amount,
b.product_code AS product_code_1,
b.product_name,
b.category
FROM sales_V0S3 AS a
RIGHT JOIN products_V0S7 AS b
ON a.product_code = b.product_code

Exemplo 4: junção externa completa​

Entrada (formato Tableau)​

{
"id": "0e1f2a3b-4c5d-6e7f-8a9b-0c1d2e3f4a5b",
"name": "Full Join Transactions",
"node_type": ".v1.SimpleJoin",
"actionNode": {
"joinType": "full",
"conditions": [
{
"comparator": "==",
"leftExpression": "[Transaction ID]",
"rightExpression": "[Transaction ID]"
}
]
}
}

SQL gerado​

SELECT
a.transaction_id,
a.amount,
a.date,
b.transaction_id AS transaction_id_1,
b.reconciled,
b.status
FROM source_a_V0S10 AS a
FULL OUTER JOIN source_b_V0S12 AS b
ON a.transaction_id = b.transaction_id

Exemplo 5: antijunção à esquerda (linhas apenas da esquerda)​

Entrada (formato Tableau)​

{
"id": "1f2a3b4c-5d6e-7f8a-9b0c-1d2e3f4a5b6c",
"name": "Find Unmatched Customers",
"node_type": ".v1.SimpleJoin",
"actionNode": {
"joinType": "leftanti",
"conditions": [
{
"comparator": "==",
"leftExpression": "[Customer ID]",
"rightExpression": "[Customer ID]"
}
]
}
}

SQL gerado​

SELECT
a.customer_id,
a.customer_name,
a.region
FROM all_customers_V0S4 AS a
LEFT ANTI JOIN active_customers_V0S8 AS b
ON a.customer_id = b.customer_id

Exemplo 6: antijunção à direita (linhas apenas da direita)​

Entrada (formato Tableau)​

{
"id": "2a3b4c5d-6e7f-8a9b-0c1d-2e3f4a5b6c7d",
"name": "Find Orphaned Records",
"node_type": ".v1.SimpleJoin",
"actionNode": {
"joinType": "rightanti",
"conditions": [
{
"comparator": "==",
"leftExpression": "[Order ID]",
"rightExpression": "[Order ID]"
}
]
}
}

SQL gerado​

SELECT
b.order_id,
b.status,
b.created_date
FROM orders_V0S6 AS a
RIGHT ANTI JOIN orphaned_orders_V0S9 AS b
ON a.order_id = b.order_id

Exemplo 7: junção com condição única​

Entrada (formato Tableau)​

{
"id": "3b4c5d6e-7f8a-9b0c-1d2e-3f4a5b6c7d8e",
"name": "Join by Region",
"node_type": ".v1.SimpleJoin",
"actionNode": {
"joinType": "inner",
"conditions": [
{
"comparator": "==",
"leftExpression": "[Region Code]",
"rightExpression": "[Region Code]"
}
]
}
}

SQL gerado​

SELECT
a.region_code,
a.sales_amount,
b.region_code AS region_code_1,
b.region_name,
b.manager
FROM sales_V0S2 AS a
INNER JOIN regions_V0S5 AS b
ON a.region_code = b.region_code

Como funciona​

1. Identificar o tipo de junção​

Lê joinType de actionNode:

{
"joinType": "inner"
}

Tipos suportados:

  • inner → INNER JOIN
  • left → LEFT JOIN
  • right → RIGHT JOIN
  • full → FULL OUTER JOIN
  • leftanti → LEFT ANTI JOIN
  • rightanti → RIGHT ANTI JOIN

2. Analisar as condições de junção​

Extrai o array conditions:

{
"conditions": [
{
"comparator": "==",
"leftExpression": "[Year]",
"rightExpression": "[Year]"
},
{
"comparator": "==",
"leftExpression": "[Month]",
"rightExpression": "[Month]"
}
]
}

3. Converter em cláusula SQL ON​

Traduz as condições em SQL:

[Year] == [Year]  →  a.year = b.year
[Month] == [Month] → a.month = b.month

Múltiplas condições são combinadas com AND:

ON a.year = b.year AND a.month = b.month

4. Tratar nomes de colunas duplicados​

Quando ambas as entradas têm os mesmos nomes de colunas:

  • Colunas de junção: Aparecem de ambos os lados (com sufixo no lado direito)
  • Colunas fora da junção: Se duplicadas, recebem sufixo no lado direito

Exemplo:

Left: year, month, sales_amount
Right: year, month, target_amount

Output:
- year (from left)
- month (from left)
- sales_amount (from left)
- target_amount (from right)
- year_1 (from right, suffixed)
- month_1 (from right, suffixed)

5. Gerar aliases de tabelas​

Cria aliases de tabelas para maior clareza:

  • Entrada esquerda: AS a
  • Entrada direita: AS b

Todas as referências a colunas recebem o prefixo do alias:

a.year, a.month, b.target_amount

6. Construir a instrução JOIN completa​

SELECT
a.column1,
a.column2,
b.column3,
b.column1 AS column1_1 -- duplicate, suffixed
FROM left_input AS a
<JOIN_TYPE> JOIN right_input AS b
ON <join_conditions>

Comparação dos tipos de junção​

INNER JOIN​

Retorna apenas linhas com correspondências em ambas as tabelas.

Left: 100 rows
Right: 80 rows
Result: 50 rows (only matches)

LEFT JOIN​

Retorna todas as linhas da tabela esquerda e NULL para linhas da direita sem correspondência.

Left: 100 rows
Right: 80 rows
Result: 100 rows (all left + matches)

RIGHT JOIN​

Retorna todas as linhas da tabela direita e NULL para linhas da esquerda sem correspondência.

Left: 100 rows
Right: 80 rows
Result: 80 rows (all right + matches)

FULL OUTER JOIN​

Retorna todas as linhas de ambas as tabelas, com NULL onde não há correspondência.

Left: 100 rows
Right: 80 rows
Result: 130 rows (all rows from both)

LEFT ANTI JOIN​

Retorna apenas linhas da tabela esquerda SEM correspondência na tabela direita.

Left: 100 rows
Right: 80 rows
Result: 50 rows (left-only rows)

RIGHT ANTI JOIN​

Retorna apenas linhas da tabela direita SEM correspondência na tabela esquerda.

Left: 100 rows
Right: 80 rows
Result: 30 rows (right-only rows)

Múltiplas condições de junção​

As condições de junção são combinadas com lógica AND:

{
"conditions": [
{"leftExpression": "[Year]", "rightExpression": "[Year]"},
{"leftExpression": "[Month]", "rightExpression": "[Month]"},
{"leftExpression": "[Region]", "rightExpression": "[Region]"}
]
}

Converte em:

ON a.year = b.year
AND a.month = b.month
AND a.region = b.region

Todas as condições devem ser satisfeitas para haver correspondência.

Padrão de sufixos para colunas duplicadas​

Quando existem nomes de colunas duplicados:

Padrão 1: duplicação de coluna de junção​

Join on: Customer ID
Left has: customer_id
Right has: customer_id

Output:
- customer_id (from left)
- customer_id_1 (from right)

Padrão 2: duplicação de coluna fora da junção​

Left has: amount, date
Right has: amount, date

Output:
- amount (from left)
- date (from left)
- amount_1 (from right)
- date_1 (from right)

Padrão 3: múltiplas duplicatas​

Left has: id, name, value
Right has: id, name, status

Output:
- id (from left)
- name (from left)
- value (from left)
- status (from right)
- id_1 (from right)
- name_1 (from right)

O sufixo é incrementado se _1 já existir: _2, _3 etc.

Limitações​

  • ⚠️ Apenas comparações de igualdade - Apenas o comparador == é suportado; sem <, >, != etc.
  • ⚠️ Apenas duas entradas - Une exatamente dois conjuntos de dados; encadeie múltiplas junções para 3 ou mais tabelas
  • ⚠️ Apenas lógica AND - Múltiplas condições são combinadas com AND; lógica OR não é suportada
  • ⚠️ Sem expressões complexas - As condições de junção devem ser referências simples a colunas

Boas práticas​

Quando usar o transformador Join​

  • ✅ Combinar conjuntos de dados relacionados - Vendas com metas, clientes com pedidos
  • ✅ Enriquecer dados - Adicionar dados de dimensão a tabelas fato
  • ✅ Encontrar correspondências/ausências de correspondência - Junções ANTI para verificações de qualidade de dados

Otimização de desempenho de junções​

  1. Filtre antes de unir - Use nós Container anteriores para reduzir a quantidade de linhas
  2. Una por colunas indexadas - Use colunas de chave primária/estrangeira quando possível
  3. Escolha o tipo de junção correto - Use INNER JOIN quando possível (mais rápido que OUTER)
  4. Minimize colunas duplicadas - Selecione apenas as colunas necessárias nos nós anteriores

Encadeamento de múltiplas junções​

Para unir 3 ou mais tabelas:

Table A → Join (A + B) → Join (AB + C) → Join (ABC + D)

Cada junção adiciona mais uma tabela ao resultado.

Tratamento de nomes duplicados​

Se os sufixos de duplicação forem indesejados:

  1. Use uma ação RenameColumn anterior para renomear colunas antes da junção
  2. Use RenameColumn posterior para ajustar os nomes com sufixo após a junção
  • UnionTransformer - Para combinar conjuntos de dados verticalmente (empilhar linhas)
  • AggregateTransformer - Para agregar os resultados de junções
  • ContainerTransformer - Para filtrar antes ou depois de junções