Entendendo JOIN

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:

 SELECT * FROM países
foreach($países as $país) {
SELECT * FROM ciudades WHERE país = $país
foreach ($ciudades as $ciudad) {


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:

SELECT * FROM localidade. AS dir
JOIN países AS p ON p.país = dir.pais
WHERE … qualquer condição

Esta busca geraria o seguinte resultado hipotético (veja que esta organizado pela coluna ‘pais’):

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

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:

id nombre       id  nombre
-- ----         --  ----
1  Pirata       1   Rutabaga
2  Mico         2   Pirata
3  Ninja        3   Darth Vader
4  Spaghetti    4   Ninja

Certo? Agora vejamos como mesclar os dados com JOIN, no caso o INNER JOIN:

SELECT * FROM TablaA
INNER JOIN TablaB
ON TablaA.name = TablaB.name

id  name       id   name
--  ----       --   ----
1   Pirata     2    Pirata
3   Ninja      4    Ninja

Como resultado teremos uma lista com registros que existam tanto em A como em B simultaneamente.

FULL OUTER JOIN

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

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

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

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:

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

Só quero ver os registros únicos que existam na tabela A

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

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:

SELECT * FROM TablaA
LEFT JOIN TablaB
ON TablaA.name = TablaB.name

… é equivalente a:

SELECT * FROM TablaB
RIGHT JOIN TablaA
ON TablaA.name = TablaB.name

Fonte: http://pt.wikibooks.org/wiki/PostgreSQL_Pr%C3%A1tico/DML/Consultas_Join

One thought to “Entendendo JOIN”

  1. 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

Leave a Reply

Your email address will not be published. Required fields are marked *