Entendendo os JOIN
Este é um problema bastante comum entre desenvolvedores que lidam com banco de dados:
Realiza-se uma busca (SELECT) e como resultado tem-se uma lista de ID´s. Agora como trazer os dados desses ID´s?
Algumas pessoas utilizam a seguinte lógica para solucionar este problema:
[sql] SELECT * FROM países
foreach($países as $país) {
SELECT * FROM ciudades WHERE país = $país
foreach ($ciudades as $ciudad) {
[/sql]
Como pode-se ver, não é apenas confuso de ler como também é impossível de crescer logicamnte. Sem falar que gera um gasto excessivo de memória.
Ai é que entra os JOIN´s…
Por exemplo, usando JOIN, pode-se ter um set de resultados de países com a seguinte query:
[sql]SELECT * FROM localidade. AS dir
JOIN países AS p ON p.país = dir.pais
WHERE … qualquer condição[/sql]
Esta busca geraria o seguinte resultado hipotético (veja que esta organizado pela coluna ‘pais’):
[sql]
p.id | p.pais | dir.id | dir.pais | dir.localidade
1 | USA | 3 | USA | 200 West Chadderdon Avenue
2 | Mexico | 4 | Mexico | 823 Monte Libano
4 | Colombia | 2 | Colombia | Carrera 9B Bis #117-32
3 | Colombia | 1 | Colombia | Calle 127 #42-45
[/sql]
Fácil né? Bem, parece simples a primeira vista, porém com isso estamos apenas raspando a superfície do problema, como por exemplo, se existir duas tabelas que não necessariamente contenham dados simétricos.
Para solucionar este problema, tem que se usar os JOINS por completo: LEFT JOIN, RIGHT JOIN, INNER JOIN e OUTER JOIN.
Vejamos o exemplo abaixo de duas tabelas que contenham alguns dados em comum:
[sql]
id nombre id nombre
— —- — —-
1 Pirata 1 Rutabaga
2 Mico 2 Pirata
3 Ninja 3 Darth Vader
4 Spaghetti 4 Ninja
[/sql]
Certo? Agora vejamos como mesclar os dados com JOIN, no caso o INNER JOIN:
[sql]
SELECT * FROM TablaA
INNER JOIN TablaB
ON TablaA.name = TablaB.name
id name id name
— —- — —-
1 Pirata 2 Pirata
3 Ninja 4 Ninja[/sql]
Como resultado teremos uma lista com registros que existam tanto em A como em B simultaneamente.
FULL OUTER JOIN
[sql]
SELECT * FROM TablaA
FULL OUTER JOIN TablaB
ON TablaA.name = TablaB.name
id name id name
— —- — —-
1 Pirata 2 Pirata
2 Mico null null
3 Ninja 4 Ninja
4 Spaghetti null null
null null 1 Rutabaga
null null 3 Darth Vader
[/sql]
Gerará uma lista com incluem todos os resultados de A e B, assim não existirá relação alguma entre os campos.
LEFT OUTER JOIN
[sql]
SELECT * FROM TablaA
LEFT OUTER JOIN TablaB
ON TablaA.name = TablaB.name;
id name id name
— —- — —-
1 Pirata 2 Pirata
2 Mico null null
3 Ninja 4 Ninja
4 Spaghetti null null
[/sql]
Todos os resultados que se encontram na tabela A e os resultados na mesma ordem na tabela B.
Usos e Derivações:
Agora que vimos como que funciona o JOIN, vejaamos outros exemplos com JOIN´s completas:
[sql]
SELECT * FROM TablaA
LEFT OUTER JOIN TablaB
ON TablaA.name = TablaB.name WHERE TablaB.id is null;
id name id name
— —- — —-
2 Mico null null
4 Spaghetti null null
[/sql]
Só quero ver os registros únicos que existam na tabela A
[sql]
SELECT * FROM TablaA
FULL OUTER JOIN TablaB
ON TablaA.name = TablaB.name
WHERE TablaA.id is null
OR TablaB.id is null
id name id name
— —- — —-
2 Mico null null
4 Spaghetti null null
null null 1 Rutabaga
null null 3 Darth Vader
[/sql]
Mostra-me os registros que não tenham relação alguma entre a tabela A e tabela B
Veja que o LEFT JOIN é intercambiável em sintaxe (mas não na lógica) com o RIGHT JOIN, onde:
[sql]
SELECT * FROM TablaA
LEFT JOIN TablaB
ON TablaA.name = TablaB.name
… é equivalente a:
SELECT * FROM TablaB
RIGHT JOIN TablaA
ON TablaA.name = TablaB.name[/sql]
Fonte: http://pt.wikibooks.org/wiki/PostgreSQL_Pr%C3%A1tico/DML/Consultas_Join
Pelo que me consta, hoje é possível ignorar as palavras inner e outer, logo:
join = inner join
left join = left outer join
right join = right outer join
full join = full outer join