# Join (SQL)

Uma cláusula join da SQL - correspondente a uma operação de junção em álgebra relacional - combina colunas de uma ou mais tabelas em um banco de dados relacional. Ela cria um conjunto que pode ser salvo como uma tabela ou usado da forma como está. Um JOIN é um meio de combinar colunas de uma (auto-junção) ou mais tabelas, usando valores comuns a cada uma delas. O SQL padrão ANSI especifica cinco tipos de JOIN: INNER, LEFT OUTER, RIGHT OUTER, FULL OUTER e CROSS. Como um caso especial, uma tabela (tabela base, visão ou tabela juntada) pode se juntar a si mesma em uma auto-união (self-join).
Um programador declara uma instrução JOIN para identificar linhas para junção. Se o predicado avaliado for verdadeiro, a linha combinada é, então, produzida no formato esperado, um conjunto de linhas ou uma tabela temporária.

## Tabelas de exemplo

Os bancos de dados relacionais geralmente são normalizados para eliminar a duplicação de informações, como quando os tipos de entidade têm relacionamentos um-para-muitos. Por exemplo, um departamento pode estar associado a vários funcionários. A junção de tabelas separadas para departamento e empregado cria, efetivamente, outra tabela que combina as informações de ambas as tabelas.
Todas as explicações subsequentes sobre tipos de junção neste artigo utilizam as duas tabelas a seguir. As linhas nessas tabelas servem para ilustrar o efeito de diferentes tipos de junções e predicados de junção. A coluna IDDepartamento da tabela Departamento (que pode ser designada como Departamento.IDDepartamento) é a chave primária, enquanto Empregado.IDDepartamento é uma chave estrangeira.
Tabela Empregado :
| ÚltimoNome | IDDepartamento |
| Rafferty | 31 |
| Jones | 33 |
| Heisenberg | 33 |
| Robinson | 34 |
| Smith | 34 |
| Williams | NULO |
Tabela Departamento :
| IDDepartamento | NomeDepartamento |
| 31 | Vendas |
| 33 | Engenharia |
| 34 | Administrativo |
| 35 | Marketing |
Observação: Na tabela Empregado acima, o empregado "Williams" ainda não foi atribuído a nenhum departamento. Além disso, observe que nenhum funcionário é atribuído ao departamento de "Marketing".
Esta é a instrução SQL para criar as tabelas acima mencionadas.

## Junção cruzada (cross join)

Uma junção cruzada, CROSS JOIN, retorna o produto cartesiano dos registros (linhas) das tabelas na junção. Em outras palavras, ela produzirá registros que combinam cada registro da primeira tabela com cada registro da segunda tabela.
Exemplo de uma junção cruzada explícita:
Exemplo de um cross join implícito:
| Empregado.ÚltimoNome | Empregado.IDDepartamento | Departamento.NomeDepartamento | Departamento.IDDepartamento |
| Rafferty | 31 | Venda | 31 |
| Jones | 33 | Venda | 31 |
| Heisenberg | 33 | Venda | 31 |
| Smith | 34 | Venda | 31 |
| Robinson | 34 | Venda | 31 |
| Williams | NULO | Venda | 31 |
| Rafferty | 31 | Engenharia | 33 |
| Jones | 33 | Engenharia | 33 |
| Heisenberg | 33 | Engenharia | 33 |
| Smith | 34 | Engenharia | 33 |
| Robinson | 34 | Engenharia | 33 |
| Williams | NULO | Engenharia | 33 |
| Rafferty | 31 | Administrativo | 34 |
| Jones | 33 | Administrativo | 34 |
| Heisenberg | 33 | Administrativo | 34 |
| Smith | 34 | Administrativo | 34 |
| Robinson | 34 | Administrativo | 34 |
| Williams | NULO | Administrativo | 34 |
| Rafferty | 31 | Marketing | 35 |
| Jones | 33 | Marketing | 35 |
| Heisenberg | 33 | Marketing | 35 |
| Smith | 34 | Marketing | 35 |
| Robinson | 34 | Marketing | 35 |
| Williams | NULO | Marketing | 35 |
A junção cruzada não aplica nenhum predicado para filtrar linhas da tabela resultante da junção. Os resultados de uma junção cruzada podem ser filtrados usando uma cláusula WHERE, que pode então produzir o equivalente a uma junção interna.
No padrão SQL:2011, as junções cruzadas fazem parte do pacote opcional F401, "Extended joined table".
Usos comuns são para verificar o desempenho do servidor.

## Junção interna (inner join)

Uma junção interna, INNER JOIN, requer que cada linha, nas duas tabelas da junção, tenha valores de coluna correspondentes, e é uma operação de junção comumente usada em aplicativos, mas não deve ser considerada a melhor escolha em todas as situações. A junção interna cria uma nova tabela de resultados combinando valores de coluna de duas tabelas (A e B) com base no predicado de junção. A consulta compara cada linha de A com cada linha de B para encontrar todos os pares de linhas que satisfazem o predicado da junção. Quando o predicado da junção é satisfeito pela correspondência de valores não-NULOS, os valores de coluna para cada par de linhas correspondentes de A e B são combinados em uma linha de resultado.
O resultado da junção pode ser definido como o resultado da primeira obtenção do produto cartesiano (ou Cross join) de todas as linhas nas tabelas (combinando todas as linhas da tabela A com todas as linhas da tabela B) e retornando todas as linhas que satisfazem o predicado da junção. Implementações SQL reais normalmente usam outras abordagens, como junções de hash ou junções de mesclagem de ordenação, pois o cálculo do produto cartesiano é mais lento e, geralmente, requer, proibitivamente, uma grande quantidade de memória para armazenar.
O SQL especifica duas formas sintáticas diferentes para expressar as junções: a "notação de junção explícita" e a "notação de junção implícita". A "notação de junção implícita" não é mais considerada uma prática recomendada, embora os sistemas de banco de dados ainda a suportem.
A "notação de junção explícita" usa a palavra-chave JOIN, opcionalmente precedida pela palavra-chave INNER, para especificar a tabela a ser unida e a palavra-chave ON para especificar os predicados para a junção, como no exemplo a seguir:
| Empregado.ÚltimoNome | Empregado.Departamento | Departamento.NomeDepartamento |
| Robinson | 34 | Administrativo |
| Jones | 33 | Engenharia |
| Smith | 34 | Administrativo |
| Heisenberg | 33 | Engenharia |
| Rafferty | 31 | Vendas |
A "notação de junção implícita" simplesmente lista as tabelas para unir, na cláusula FROM da instrução SELECT, usando vírgulas para separá-las. Assim, ele especifica uma junção cruzada, e a cláusula WHERE pode aplicar predicados de filtro adicionais (que funcionam comparativamente aos predicados da junção na notação explícita).
O exemplo a seguir é equivalente ao anterior, mas desta vez usando notação de junção implícita:

## Junção externa (outer join)

A tabela resultante da junção retém cada linha - mesmo que não exista outra linha correspondente. As junções externas subdividem-se, adicionalmente, em junções externas esquerdas (left outer joins), junções externas direitas (right outer joins) e junções externas completas (full outer joins), dependendo de quais linhas da tabela são retidas: esquerda, direita ou ambas (neste caso, esquerda e direita referem-se aos dois lados da palavra-chave JOIN). Assim como as junções internas, pode-se ainda sub-categorizar todos os tipos de junções externas, como junções de igualdade, junções naturais, ON <predicado> (junção-θ ou θ-join), etc.
Não existe nenhuma notação de junção implícita para junções externas no SQL padrão.

### Junção externa esquerda (left outer join)

O resultado de uma junção externa esquerda (ou simplesmente junção esquerda - left join) para as tabelas A e B sempre contém todas as linhas da tabela "esquerda" (A), mesmo se a condição de junção não encontrar nenhuma linha correspondente na tabela "direita" (B). Isso significa que se a cláusula ON corresponder a 0 (zero) linhas em B (para uma determinada linha em A), a união ainda retornará uma linha no resultado (para aquela linha) - mas com NULO em cada coluna de B. Uma junção externa esquerda retorna todos os valores de uma junção interna mais todos os valores na tabela à esquerda que não correspondem à tabela da direita, incluindo linhas com valores NULO (vazios) na coluna de ligação.
Por exemplo, isso nos permite encontrar o departamento de um funcionário, mas ainda mostra funcionários que não foram atribuídos a um departamento (ao contrário do exemplo de associação interna acima, em que funcionários não atribuídos foram excluídos do resultado).
Exemplo de uma junção externa esquerda (a palavra-chave OUTER é opcional), com a linha de resultado adicional (comparada com a junção interna) em itálico:
| Empregado.ÚltimoNome | Empregado.IDDepartamento | Departamento.NomeDepartamento | Departamento.IDDepartamento |
| Jones | 33 | Engenharia | 33 |
| Rafferty | 31 | Vendas | 31 |
| Robinson | 34 | Administrativo | 34 |
| Smith | 34 | Administrativo | 34 |
| Williams | NULO | NULO | NULO |
| Heisenberg | 33 | Engenharia | 33 |

#### Sintaxes alternativas

O Oracle suporta a sintaxe depreciada:
O Sybase suporta a sintaxe (o Microsoft SQL Server depreciou essa sintaxe desde a versão 2000):
O IBM Informix suporta a sintaxe:

### Junção externa direita (right outer join)

Uma junção externa direita (junção direita ou right join) se assemelha a uma junção externa esquerda, exceto com o tratamento das tabelas invertidas. Cada linha da tabela "direita" (B) aparecerá na tabela resultante da junção pelo menos uma vez. Se nenhuma linha correspondente da tabela "esquerda" (A) existir, aparecerá NULO nas colunas de A para aquelas linhas que não tiverem correspondência em B.
Uma junção externa direita retorna todos os valores da tabela da direita e os valores correspondentes da tabela da esquerda (NULO no caso de nenhum predicado de junção correspondente). Por exemplo, isso nos permite encontrar cada funcionário e seu departamento, mas ainda mostrar departamentos que não possuem funcionários.
Abaixo está um exemplo de uma junção externa direita (a palavra-chave OUTER é opcional), com a linha de resultado adicional em itálico:
| Empregado.ÚltimoNome | Empregado.IDDepartamento | Departamento.NomeDepartamento | Departamento.IDDepartamento |
| Smith | 34 | Administrativo | 34 |
| Jones | 33 | Engenharia | 33 |
| Robinson | 34 | Administrativo | 34 |
| Heisenberg | 33 | Engenharia | 33 |
| Rafferty | 31 | Vendas | 31 |
| NULO | NULO | Marketing | 35 |
Junções externas esquerda e direita são funcionalmente equivalentes. Nenhuma das duas fornece qualquer funcionalidade que a outra não tenha, portanto, as junções externas direita e esquerda podem substituir umas às outras, desde que a ordem da tabela seja trocada.

### Junção externa completa (full outer join)

Conceitualmente, uma junção externa completa combina o efeito de aplicar junções externas esquerda e direita. Onde as linhas nas tabelas que forem unidas pela junção completa não corresponderem, o conjunto de resultados terá valores NULO para cada coluna da tabela que não possuir uma linha correspondente. Para aquelas linhas que corresponderem, uma única linha será produzida no conjunto de resultados (contendo colunas preenchidas de ambas as tabelas).
Por exemplo, isso nos permite ver cada funcionário que está em um departamento e cada departamento que tem um funcionário, mas também ver cada funcionário que não faz parte de um departamento e cada departamento que não tem um funcionário.
Exemplo de uma junção externa completa (a palavra-chave OUTER é opcional):
| Empregado.ÚltimoNome | Empregado.IDDepartamento | Departamento.NomeDepartamento | Departamento.IDDepartamento |
| Smith | 34 | Administrativo | 34 |
| Jones | 33 | Engenharia | 33 |
| Robinson | 34 | Administrativo | 34 |
| Williams | NULO | NULO | NULO |
| Heisenberg | 33 | Engenharia | 33 |
| Rafferty | 31 | Administrativo | 31 |
| NULO | NULO | Marketing | 35 |
Alguns sistemas de banco de dados não suportam a funcionalidade de junção externa completa diretamente, mas podem emular através do uso de uma junção interna e de seleções UNION ALL das "linhas de tabela única" das tabelas esquerda e direita, respectivamente. O mesmo exemplo pode aparecer da seguinte maneira: