Utilizando a função NATURAL JOIN
A utilização de um JOIN em uma consulta ou em uma subconsulta de banco de dados é muito comum para a utilização nos relacionamentos (pode também ser efetuada na clausula WHERE), e muitas vezes nos submetemos a criar muitos relacionamentos, tendo que declarar qual campo deverá ser relacionado com campo de “TABELA A” com campo de “TABELA B”, e isto acaba gerando muitas linhas de código, tornando muitas vezes o próprio código muito complexo e extenso, mas existe uma forma mais fácil e prática para poder eliminar tais linhas de códigos simplificando um pouco o código da consulta, que é o NATURAL JOIN (Junção Natural).
A junção natural é baseada em todas as colunas nas duas tabelas que possuem o mesmo nome, ela seleciona linhas das duas tabelas que têm valores iguais nas colunas relevantes, por exemplo: TABELA1.CAMPO1 e TABELA2.CAMPO1, neste caso, se utilizado o NATURAL JOIN, o Oracle entenderá que estas duas colunas de ambas as tabelas são relacionadas e possuem os mesmos dados, com isso, o banco de dados irá agregar as colunas mostrando no resultado da consulta apenas uma coluna.
O que não pode acontecer é TABELA1.CAMPO1 e TABELA2.CAMPO2, neste caso o NATURAL JOIN não irá efetuar a operação corretamente, não será mostrado erro, pois o Oracle tentará efetuar a operação, mas os resultados estarão duplicados, conforme a quantidade de registros que esteja em ambas as tabelas devido à sua cardinalidade.
Alguns exemplos da prática de NATURAL JOIN para o usuário HR do Oracle:
SELECT * FROM COUNTRIES NATURAL JOIN (LOCATIONS);
Reparamos que neste caso, o resultado obtido foi igualmente ao que um relacionamento de ambas as tabelas teria feito, seja feita pelo WHERE ou então com um INNER JOIN. Também podemos notar que a coluna COUNTRY_ID que existe nas duas tabelas virou apenas uma. A quantidade total de registros é de 23.
Para afins de testes e comprovar a teoria em que os registros irão se duplicar caso seja feita um NATURAL JOIN com todas as colunas com nomes diferentes, basta alterar o campo COUNTRY_ID de alguma tabela e executar o comando novamente, neste caso os registros passaram de 500 e também vale notar que aparecem todas as colunas, e que nenhuma foi agregada.
O NATURAL JOIN pode ser utilizado com o acompanhamento de outros JOINS, como por exemplo: INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN e FULL OUTER JOIN.
Mais alguns exemplos de NATURAL JOIN juntamente com os outros JOINS:
Exemplo 01 – Com o INNER JOIN a junção natural permanece igual aos seus resultados:
SELECT * FROM COUNTRIES NATURAL INNER JOIN (LOCATIONS);
Exemplo 02 – No LEFT OUTER JOIN com a junção natural, os resultados da tabela da esquerda prevalecem sobre os registros da tabela da direita, resultando nos valores nulos para a tabela da direita, que no caso é a LOCATIONS.
SELECT * FROM COUNTRIES NATURAL LEFT OUTER JOIN (LOCATIONS);
Exemplo 04 – Como a tabela da direita não possuí os códigos dos países (COUNTRY_ID) e que são inexistentes na tabela COUNTRIES, o resultado será igual ao INNER JOIN.
SELECT * FROM COUNTRIES NATURAL RIGHT OUTER JOIN (LOCATIONS);
Exemplo 03 – Neste caso acontecerá o mesmo que o LEFT OUTER JOIN para a o comando FULL OUTER JOIN, que resultará nos registros de todos os lados.
SELECT * FROM COUNTRIES NATURAL FULL OUTER JOIN (LOCATIONS);
Exemplo 04 – Neste próximo exemplo será alterado a tabela pai, e também será mostrado uma junção natural com duas tabelas relacionadas
SELECT * FROM LOCATIONS NATURAL JOIN (COUNTRIES INNER JOIN REGIONS ON REGIONS.REGION_ID = COUNTRIES.REGION_ID);
Este exemplo mostra que a tabela LOCATIONS que possuí a coluna COUNTRY_ID que é relacionada com a tabela COUNTRIES, e a tabela COUNTRIES é efetuada um relacionamento de junção normal com a tabela REGIONS pelo campo REGION_ID. Porém estas duas tabelas também poderia ser relacionadas com um NATURAL JOIN, pois possuem o mesmo nome das colunas.
Exemplo 05 – Junções naturais relacionadas com outras junções naturais, isto tudo para agregar todos as colunas no momento de efetuar a operação com asterisco (*).
SELECT * FROM LOCATIONS NATURAL JOIN (COUNTRIES NATURAL JOIN (REGIONS));
Desta forma iremos obter o mesmo resultado que o exemplo número 04.
Segundo a documentação da Oracle, existem algumas restrições no momento de efetuar o NATURAL JOIN.
- Não é permitido colunas do tipo LOB;
- Não são permitidas colunas ANYTYPE, ANYDATA ou ANYDATASET;
- Colunas com uma parte de um NATURAL JOIN;
- Não é possível especificar TABELA.CAMPO dentro de um NATURAL JOIN (erro ORA-00942 – A tabela ou view não existe);
Quanto à sua diferença no desempenho no momento da execução, nos testes efetuados para este artigo não foram encontradas diferenças quanto ao custo para o banco de dados, ambos efetuaram a mesma operação, obtiveram a mesma cardinalidade e também o mesmo custo.
Também há uma consideração a ser feito, quanto ao cuidado de se utilizar um NATURAL JOIN, caso uma tabela tenha colunas com o mesmo nome e o desenvolvedor utilizar o NATURAL JOIN sabendo que alguma dessas colunas poderá possuir valores nulos (ou diferentes) o relacionamento não acontecerá, pois, o NATURAL JOIN funciona muito bem quando uma coluna é chave estrangeira da outra tabela. Exemplo:
TABELA A:
Código |
Nome |
Dt. Nasc. |
Nom Usuário |
Dt. Cad. |
1 |
Leandro M. Bonato |
16/02/1991 |
Leandro.bonato |
10/04/2016 |
2 |
Fulano |
30/12/1992 |
Fulano.ciclano |
09/04/2016 |
TABELA B
Seq. |
Código |
Dt. Cad. |
Dt. Acesso |
Nome |
Obs. |
Site |
1 |
1 |
10/04/2016 |
10/04/2016 |
Leandro M. Bonato |
GPO |
|
2 |
2 |
09/04/2016 |
10/04/2016 |
Fulano |
GPO |
|
3 |
2 |
10/04/2016 |
10/04/2016 |
Fulano |
GPO |
|
4 |
2 |
09/04/2016 |
10/04/2016 |
Ciclano |
GPO |
|
5 |
1 |
10/04/2016 |
10/04/2016 |
Leandro M. |
GPO |
|
No Exemplo acima vemos claramente que aparecerá apenas os dois primeiros registros da TABELA B, devido que os nomes dos campos que são iguais à TABELA A possuem valores diferentes com os da TABELA B, por este motivo utiliza-se com mais frequência o INNER JOIN, que neste caso conseguiríamos relacionar apenas o campo código, que é o campo de relacionamento padrão entre as tabelas.
Referências
Abraços