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

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

5 celulares para NÃO COMPRAR em 2021

Conteúdo relacionado

Análise FIFA 22 - Quando o realismo entra em campo
Games

Análise FIFA 22 - Quando o realismo entra em campo

a HyperMotion Technology permite que o jogo entregue bastante realismo, com grande destaque para o posicionamento dos atletas! Confira o que achamos do jogo.

Como criar um campo auto-increment no PostgreSQL
Programação

Como criar um campo auto-increment no PostgreSQL

Para aqueles que usam MySQL, estão muito acostumados em habilitar a opção auto_increment em uma chave primária para criar uma coluna que incrementa automaticamente um valor a cada novo insert na tabela.

10 dicas para iniciar em PostgreSQL
Programação

10 dicas para iniciar em PostgreSQL

Como vejo muitas pessoas novas utilizando o PostgreSQL, deixo aqui as minhas observações que podem ser petulantes ou óbvias para muitos, mas julgo ser de interesse de quem está realmente começando.