Capítulo 2
1-Junções
Na prática, um Banco de Dados não terá apenas uma tabela. Seja por motivo de organização dos dados, seja por questão de acesso a diferentes categorias de dados, geralmente organizamos o Banco em várias tabelas, que se relacionam entre si.
Portanto, geralmente, as consultass são feitas em várias tabelas simultaneamente. Para realizar consultas em mais de uma tabela usamos as junções (joins).
Nós vimos um exemplo "motivacional" quando fizemos uma consulta no Banco de Dados World.
No exemplo, mostramos que se fizermos a consulta apenas na tabela Country nós conseguiremos apenas obter o código do páis.
Para termos o resultado correto (país e capital) precisamos buscar o nome do páis, a partir do seu código.
(Veja nossa explicação nas páginas 11 e 12 desse texto)Exemplo com Consulta em duas Tabelas
mysql> select Name,Capital from Country where Continent = "South America";
+------------------+---------+
| Name | Capital |
+------------------+---------+
| Argentina | 69 |
| Bolivia | 194 |
| Brazil | 211 |
| Chile | 554 |
| Colombia | 2257 |
| Ecuador | 594 |
| Falkland Islands | 763 |
| French Guiana | 3014 |
| Guyana | 928 |
| Peru | 2890 |
| Paraguay | 2885 |
| Suriname | 3243 |
| Uruguay | 3492 |
| Venezuela | 3539 |
+------------------+---------+
14 rows in set (0.02 sec)
-------------------------------------------
mysql> select C.Name,T.Name
from Country C
inner join City T
ON C.Continent = "South America"
and
T.ID = C.Capital
+------------------+---------------------+
| Name | Name |
+------------------+---------------------+
| Argentina | Buenos Aires |
| Bolivia | La Paz |
| Brazil | Brasília |
| Chile | Santiago de Chile |
| Colombia | Santafé de Bogotá |
| Ecuador | Quito |
| Falkland Islands | Stanley |
| French Guiana | Cayenne |
| Guyana | Georgetown |
| Peru | Lima |
| Paraguay | Asunción |
| Suriname | Paramaribo |
| Uruguay | Montevideo |
| Venezuela | Caracas |
+------------------+---------------------+
14 rows in set (0.06 sec)
As junções, portanto, são usadas para coletarmos informações de mais de uma tabela. Ou seja, elas fazem "ligações" entre tabelas. Essas ligações são realizadas a partir dos valores de uma ou mais colunas.
Estudando Junções com Exemplos
Para entendermos melhor como são feitas as junções (que apesar de serem intuitivas, muitas vezes podem causar alguma confusão), vamos partir de exemplos simples, usando duas tabelas com apenas duas colunas.
Os exemplos que se seguem foram baseados numa explicação bem didática que pode ser encontrada nesse link.
Tabelas para Exemplos
Vamos usar duas tabelas (TabelaA e TabelaB), como mostrado abaixo:
Duas Tabelas para Estudo de Junções
mysql> select * from TabelaA;
+---------+-------+
| Nome | Chave |
+---------+-------+
| José | 1 |
| Maria | 3 |
| Renata | 4 |
| Roberto | 8 |
+---------+-------+
4 rows in set (0.00 sec)
mysql> select * from TabelaB;
+------------+-------+
| Profissao | Chave |
+------------+-------+
| Estivador | 1 |
| Gerente | 3 |
| Porteiro | 5 |
| Engenheiro | 8 |
+------------+-------+
4 rows in set (0.00 sec)
Junção Interna - Inner Join
O diagrama apresentado acima exemplifica o que é uma junção interna: uma busca por valores na interseção de dois conjuntos.
A junção interna entre tabelas é a modalidade de junção que faz com que somente participem da relação resultante as linhas das tabelas de origem que antenderem à cláusula de junção. A sintaxe básica é:
Sintaxe Junção Interna
SELECT col1, col2,...,colN, funcao1,...,funcao2
FROM tabela1
INNER JOIN tabela2
ON tabela1.col1=tabela2.col1
WHERE condicao
GROUP BY col1,col2,...,colN
HAVING expressao_logica
ORDER BY col1,col2,...,colN
sendo,
SELECT e FROM: comandos da seleção
col1,col2,...,colN: as N colunas da tabela
tabela1 e tabela2: tabelas envolvidas na junção
funcao1, funcao2,...,funcaoN: Funções agregadas (opcional)
WHERE, GROUP BY, HAVING e ORDER BY: cláusulas opcionais
INNER JOIN: cláusula que especifica que está sendo feita uma junção interna
entre as tabelas tabela1 e tabela2.
A utilização dessa cláusula não é obrigatória.
Ela é usada para definir melhor o comando.
ON: identifica quais as colunas que serão usadas para realizar a junção.
Inner Join nas Tabelas "TabelaA e TabelaB"
Inner Join - Junção Interna
mysql> select TabelaA.*,TabelaB.*
-> from TabelaA INNER JOIN TabelaB
-> ON TabelaA.Chave = TabelaB.Chave;
+---------+-------+------------+-------+
| Nome | Chave | Profissao | Chave |
+---------+-------+------------+-------+
| José | 1 | Estivador | 1 |
| Maria | 3 | Gerente | 3 |
| Roberto | 8 | Engenheiro | 8 |
+---------+-------+------------+-------+
3 rows in set (0.00 sec)
Importante
É importante sabermos que podemos fazer consulta em duas tabelas sem usar a cláusula INNER JOIN. Podemos, por exemplo, usar a instrução "SELECT FROM" aplicada às colunas envolvidas. Veja o exemplo a seguir:
Consulta a duas Tabelas, sem usar INNER JOIN
mysql> select TabelaA.*,TabelaB.* from TabelaA,TabelaB where TabelaA.Chave = TabelaB.Chave;
+---------+-------+------------+-------+
| Nome | Chave | Profissao | Chave |
+---------+-------+------------+-------+
| José | 1 | Estivador | 1 |
| Maria | 3 | Gerente | 3 |
| Roberto | 8 | Engenheiro | 8 |
+---------+-------+------------+-------+
3 rows in set (0.00 sec)
Junções Externas
Conceito
Como vimos acima, na junção interna só participam dos resultados as linhas cujas colunas de junção possuem os mesmos valores em ambas as tabelas.
Na junção externa mesmo não havendo igualdade de valores as linhas de uma determinada tabela aparecem todas, dependendo do tipo de junção que se faz.
Temos junções externas do tipo:
à Esquerda (LEFT JOIN)
à Direita (RIGHT JOIN)
Completa (FULL JOIN)
Junção Externa à Esquerda (LEFT JOIN) ou (LEFT OUTER JOIN)
O diagrama apresentado acima exemplifica o que é uma junção à esquerda (ou junção externa à esquerda): todos elementos do conjunto à esquerda! (incluindo a parte de interseção).
Em uma junção externa à esquerda, a junção ocorre de forma que todas as linhas pertencentes à tabela posicionada à esquerda do termo LEFT OUTER JOIN (ou LEFT JOIN) e que atendam aos critérios definidos na cláusula WHERE farão parte da relação resultado, mesmo se não existirem valores correspondentes na coluna de junção da tabela posicionada a direita do comando.
Caso não exista valor correspondente na tabela á direita, as colunas selecionadas desta tabela, nas linhas onde não existem correspondência, terão valor NULL.
A junção externa à esquerda, que possui a sintaxe:
LEFT OUTER JOIN
SELECT col1, col2,...,colN, funcao1,...,funcao2
FROM tabela1
LEFT OUTER JOIN tabela2
ON tabela1.col1=tabela2.col1
WHERE condicao
GROUP BY col1,col2,...,colN
HAVING expressao_logica
ORDER BY col1,col2,...,colN
Sendo...
SELECT e FROM: comandos da seleção
col1,col2,...,colN: as N colunas da tabela
tabela1 e tabela2: tabelas envolvidas na junção
funcao1, funcao2,...,funcaoN: Funções agregadas (opcional)
WHERE, GROUP BY, HAVING e ORDER BY: cláusulas opcionais
LEFT OUTER JOIN: cláusula que especifica que está sendo feita
uma junção externa à esquerda entre as tabelas tabela1 e tabela2.
ON: identifica quais as colunas que serão usadas para realizar a junção.
Exemplo de LEFT JOIN para TabelaA e TabelaB
LEFT JOIN
mysql> select * from TabelaA;
+---------+-------+
| Nome | Chave |
+---------+-------+
| José | 1 |
| Maria | 3 |
| Renata | 4 |
| Roberto | 8 |
+---------+-------+
4 rows in set (0.00 sec)
mysql> select TabelaA.*,TabelaB.*
-> FROM TabelaA LEFT JOIN TabelaB
-> ON TabelaA.Chave = TabelaB.Chave;
+---------+-------+------------+-------+
| Nome | Chave | Profissao | Chave |
+---------+-------+------------+-------+
| José | 1 | Estivador | 1 |
| Maria | 3 | Gerente | 3 |
| Renata | 4 | NULL | NULL |
| Roberto | 8 | Engenheiro | 8 |
+---------+-------+------------+-------+
4 rows in set (0.00 sec)
Podemos escrever usando LEFT OUTER JOIN:
LEFT OUTER JOIN
mysql> select TabelaA.*,TabelaB.*
-> FROM TabelaA LEFT OUTER JOIN TabelaB
-> ON TabelaA.Chave = TabelaB.Chave;
+---------+-------+------------+-------+
| Nome | Chave | Profissao | Chave |
+---------+-------+------------+-------+
| José | 1 | Estivador | 1 |
| Maria | 3 | Gerente | 3 |
| Renata | 4 | NULL | NULL |
| Roberto | 8 | Engenheiro | 8 |
+---------+-------+------------+-------+
4 rows in set (0.01 sec)
Junção Externa à DIREITA (RIGHT JOIN) ou (RIGHT OUTER JOIN)
O diagrama apresentado acima exemplifica o que é uma junção à direita (ou junção externa à direita): todos elementos do conjunto à direita! (incluindo a parte de interseção).
Em uma junção externa à direita, a junção ocorre de forma que todas as linhas pertencentes à tabela posicionada à direita do termo RIGHT OUTER JOIN (ou RIGHT JOIN) e que atendam aos critérios definidos na cláusula WHERE farão parte da relação resultado, mesmo se não existirem valores correspondentes na coluna de junção da tabela posicionada a direita do comando.
Caso não exista valor correspondente na tabela á esquerda, as colunas selecionadas desta tabela, nas linhas onde não existem correspondência, terão valor NULL.
A junção externa à direita, que possui a sintaxe:
RIGHT OUTER JOIN
SELECT col1, col2,...,colN, funcao1,...,funcao2
FROM tabela1
RIGHT OUTER JOIN tabela2
ON tabela1.col1=tabela2.col1
WHERE condicao
GROUP BY col1,col2,...,colN
HAVING expressao_logica
ORDER BY col1,col2,...,colN
Sendo...
SELECT e FROM: comandos da seleção
col1,col2,...,colN: as N colunas da tabela
tabela1 e tabela2: tabelas envolvidas na junção
funcao1, funcao2,...,funcaoN: Funções agregadas (opcional)
WHERE, GROUP BY, HAVING e ORDER BY: cláusulas opcionais
RIGHT OUTER JOIN: cláusula que especifica que está sendo feita
uma junção externa à esquerda
entre as tabelas tabela1 e tabela2.
ON: identifica quais as colunas que serão usadas para realizar a junção.
Exemplo de RIGHT JOIN para TabelaA e TabelaB
RIGHT JOIN
mysql> select * FROM TabelaB;
+------------+-------+
| Profissao | Chave |
+------------+-------+
| Estivador | 1 |
| Gerente | 3 |
| Porteiro | 5 |
| Engenheiro | 8 |
+------------+-------+
mysql> SELECT TabelaA.*, TabelaB.*
-> FROM TabelaA RIGHT JOIN TabelaB
-> ON TabelaA.Chave = TabelaB.Chave;
+---------+-------+------------+-------+
| Nome | Chave | Profissao | Chave |
+---------+-------+------------+-------+
| José | 1 | Estivador | 1 |
| Maria | 3 | Gerente | 3 |
| NULL | NULL | Porteiro | 5 |
| Roberto | 8 | Engenheiro | 8 |
+---------+-------+------------+-------+
4 rows in set (0.01 sec)
Podemos escrever usando RIGHT OUTER JOIN:
RIGHT OUTER JOIN
mysql> SELECT TabelaA.*, TabelaB.*
-> FROM TabelaA RIGHT OUTER JOIN TabelaB
-> ON TabelaA.Chave = TabelaB.Chave;
+---------+-------+------------+-------+
| Nome | Chave | Profissao | Chave |
+---------+-------+------------+-------+
| José | 1 | Estivador | 1 |
| Maria | 3 | Gerente | 3 |
| NULL | NULL | Porteiro | 5 |
| Roberto | 8 | Engenheiro | 8 |
+---------+-------+------------+-------+
4 rows in set (0.00 sec)
Junção Externa COMPLETA (FULL OUTER JOIN) ou (FULL JOIN)
O diagrama apresentado acima exemplifica uma junção completa (FULL JOIN).
SQL FULL JOIN
Na linguagem SQL temos a opção de mostrar todas os registros das tabelas envolvidas na junção. Para isso usamos a JUNÇÃO COMPLETA (FULL JOIN).
Na FULL JOIN obtemos a listagem de todas as linhas das tabelas participantes e que atendam aos critérios de seleção especificados na cláusula WHERE. A diferença da junção externa completa paras as junções a direita e a esquerda é nessas últimas, apenas uma das tabelas fornece todos os dados, mesmo quando não há correspondência. Na junção externa completa, as duas tabelas poderão apresentar valores sem correspondentes.
Sintaxe da FULL JOIN na SQL
RIGHT OUTER JOIN
SELECT col1, col2,...,colN, funcao1,...,funcaoN
FROM NOME_TABELA
FULL OUTER JOIN NOME_TABELA2
ON NOME_TABELA.col1 = NOME_TABELA2.col1
WHERE CONDICAO
GROUP BY COL1,COL2,...COLN
HAVING expressao_logica
ORDER BY COL1,COL2,...COLN
Sendo...
SELECT e FROM: comandos da seleção
col1,col2,...,colN: as N colunas da tabela
tabela1 e tabela2: tabelas envolvidas na junção
funcao1, funcao2,...,funcaoN: Funções agregadas (opcional)
WHERE, GROUP BY, HAVING e ORDER BY: cláusulas opcionais
FULL OUTER JOIN: cláusula que especifica que está sendo feita
uma junção externa COMPLETA
entre as tabelas tabela1 e tabela2.
ON: identifica quais as colunas que serão usadas para realizar a junção.