Junção de tabelas

Até agora as consultas somente acessaram uma tabela de cada vez. As consultas podem acessar várias tabelas de uma vez, ou acessar a mesma tabela de uma maneira que várias linhas da tabela sejam processadas ao mesmo tempo

Por | @oficinadanet Programação
Até agora as consultas somente acessaram uma tabela de cada vez. As consultas podem acessar várias tabelas de uma vez, ou acessar a mesma tabela de uma maneira que várias linhas da tabela sejam processadas ao mesmo tempo. A consulta que acessa várias linhas da mesma tabela, ou de tabelas diferentes, de uma vez, é chamada de consulta de junção. Como exemplo, suponha que se queira listar todas as linhas de clima junto com a localização da cidade associada.

Para se fazer isto, é necessário comparar a coluna cidade de cada linha da tabela clima com a coluna nome de todas as linhas da tabela cidades, e selecionar os pares de linha onde estes valores são correspondentes.

Nota: Este é apenas um modelo conceitual, a junção geralmente é realizada de uma maneira mais eficiente que comparar de verdade cada par de linhas possível, mas isto não é visível para o usuário.

Esta operação pode ser efetuada por meio da seguinte consulta:
SELECT * FROM clima, cidades WHERE cidade = nome;

São Francisco   |    46 |    50 | 0.25 | 1994-11-27 | São Francisco | (-194,53)
São Francisco   |    43 |    57 |    0 | 1994-11-29 | São Francisco | (-194,53)
(2 linhas)


Duas coisas devem ser observadas no resultado produzido:
Não existe nenhuma linha para a cidade Hayward. Isto acontece porque não existe entrada correspondente na tabela cidades para Hayward, e a junção ignora as linhas da tabela clima sem correspondência. Veremos em breve como isto pode ser mudado.

Existem duas colunas contendo o nome da cidade, o que está correto porque a lista de colunas das tabelas clima e cidades estão concatenadas. Na prática isto não é desejado, sendo preferível, portanto, escrever a lista das colunas de saída explicitamente em vez de utilizar o *:
SELECT cidade, temp_min, temp_max, prcp, data, localizacao 
FROM clima, cidades WHERE cidade = nome;


Como todas as colunas possuem nomes diferentes, o analisador encontra automaticamente a tabela que a coluna pertence, mas é um bom estilo qualificar completamente os nomes das colunas nas consultas de junção:

SELECT clima.cidade, clima.temp_min, clima.temp_max,clima.prcp, clima.data, cidades.localizacao
FROM clima, cidades WHERE cidades.nome = clima.cidade;


As consultas de junção do tipo visto até agora também poderiam ser escritas da seguinte forma alternativa:
SELECT * FROM clima INNER JOIN cidades ON (clima.cidade = cidades.nome);


A utilização desta sintaxe não é tão comum quanto a usada acima, mas é mostrada para ajudar a entender os próximos tópicos.

Agora vamos descobrir como se faz para obter as linhas de Hayward. Desejamos o seguinte: que a consulta varra a tabela clima e, para cada uma de suas linhas, encontre a linha correspondente na tabela cidades. Se não for encontrada nenhuma linha correspondente, desejamos que sejam colocados “valores vazios” nas colunas da tabela cidades. Este tipo de consulta é chamada de junção externa (outer join). As consultas vistas até agora são junções internas (inner join). O comando então fica assim:

SELECT * FROM clima LEFT OUTER JOIN cidades ON (clima.cidade = cidades.nome);

Hayward       |     37 |       54 |      | 1994-11-29 |               |
São Francisco |     46 |       50 | 0.25 | 1994-11-27 | São Francisco | (-194,53)
São Francisco |     43 |       57 |    0 | 1994-11-29 | São Francisco | (-194,53)
(3 linhas)


Esta consulta é chamada de junção externa esquerda (left outer join), porque a tabela mencionada à esquerda do operador de junção terá cada uma de suas linhas aparecendo na saída pelo menos uma vez, enquanto a tabela à direita terá somente as linhas correspondendo a alguma linha da tabela à esquerda aparecendo na saída. Ao listar uma linha da tabela à esquerda, para a qual não existe nenhuma linha correspondente na tabela à direita, são colocados valores vazios (null) nas colunas da tabela à direita.

Também é possível fazer a junção da tabela consigo mesma. Isto é chamado de autojunção (self join). Como exemplo, suponha que desejamos descobrir todas as linhas de clima que estão no intervalo de temperatura de outros registros de clima. Para isso é necessário comparar as colunas temp_min e temp_max de cada registro de clima com as colunas temp_min e temp_max de todos os outros registros da tabela clima, o que pode ser feito utilizando a seguinte consulta:
SELECT C1.cidade, C1.temp_min AS menor, C1.temp_max AS maior,
C2.cidade, C2.temp_min AS menor, C2.temp_max AS maior
FROM clima C1, clima C2
WHERE C1.temp_min < C2.temp_min
AND C1.temp_max > C2.temp_max;

     cidade      | menor | maior |     cidade    | menor | maior
-----------------+-------+-------+---------------+-------+-------
São Francisco   |    43 |    57 | São Francisco |    46 |    50
Hayward         |    37 |    54 | São Francisco |    46 |    50
(2 linhas)


A tabela clima teve seu nome mudado para C1 e C2, para permitir distinguir o lado esquerdo do lado direito da junção. Estes tipos de “aliases” também podem ser utilizados em outras consultas para reduzir a digitação como, por exemplo:
SELECT * FROM clima w, cidades c WHERE w.cidade = c.nome;


Será vista esta forma de abreviar com bastante freqüência.

Mais sobre: postgresql, banco de dados, select
Share Tweet
DESTAQUESMais compartilhados
Comentários