quarta-feira, 2 de setembro de 2020

Tipos de Joins

Fala, galera.

Mais um assunto muito legal, e muito utilizado no dia a dia de quem trabalha com Oracle ou com qualquer outro banco de dados relacional.

O Join é a ferramenta básica do dia a dia de trabalho em um banco de dados relacional, é uma ferramenta que pode ser usada p/ recuperação de dados em qualquer banco, seja ele SQL Server, DB2, Oracle, Postgre, MYSQL, enfim, creio que esses sejam os mais utilizados atualmente.

Antes de começar a falar dos tipos de Joins, quero comentar um pouco a respeito do padrão ANSI-(American National Standards Institute).

O ANSI foi muito importante na definição de padrões no começo da internet, o que também definiu o padrão pra escrita de JOINS - (ANSI-SQL), ou seja para que o seu JOIN funcione em qualquer banco de dados relacional, o mesmo precisa ser escrito no padrão ANSI-SQL. Para mais informações sobre essa empresa acesse: www.ansi.org.

Como o foco desse blog é falar de Oracle, vou demonstrar os JOINS utilizando o padrão ANSI-SQL e também utilizando a forma de escrita em PL/SQL.

Dai você pode estar se perguntando, por que perder tempo entendendo como funciona o padrão ANSI-SQL? E é ai que vem o pulo do gato, se você for estudar pra tirar qualquer certificação Oracle, vai perceber que as queries que estão nos materiais de estudo/ provas, estão no padrão ANSI-SQL, portanto se você pensa em tirar alguma certificação, vai ter que aprender o padrão. Outra vantagem desse tipo de escrita é a  possibilidade de migrar as queries p/ qualquer outro banco de dados relacional sem precisar alterar, ou seja, existem muitas vantagens em utilizar desse padrão, mas vamos lá que tem muita coisa legal pra falarmos.

A palavra-chave JOIN é utilizada p/ obter dados de duas ou mais tabelas baseado em um relacionamento de colunas destas tabelas.

Para ajudar na demonstração dos tipos de Joins criei as duas tabelas abaixo, e inclui alguns registros.

CREATE TABLE turma(cod_turma  int primary key

                            ,nm_turma   VARCHAR2(50))

/

CREATE TABLE aluno(cod_aluno  int primary key

                  ,nm_aluno   VARCHAR2(50)

                  ,cod_turma  NUMBER)

/

INSERT INTO turma VALUES(1, 'Manhã');

INSERT INTO turma VALUES(2, 'Tarde');

INSERT INTO turma VALUES(3, 'Noite')

/

COMMIT;

INSERT INTO aluno VALUES(1, 'Ana Luiza', NULL);

INSERT INTO aluno VALUES(2, 'Ana Paula', 1);

INSERT INTO aluno VALUES(3, 'Guilherme Pereira', 1);

INSERT INTO aluno VALUES(4, 'Vinicius Silva', 2);

INSERT INTO aluno VALUES(5, 'Leonardo Mattos', NULL)

/

COMMIT;


Tipos de JOINS 

*INNER JOIN 

Este é o formato mais comum de JOIN, que irá retornar apenas os dados com informações correspondentes nas duas tabelas.

No caso abaixo, eu trago os registros dos alunos que estejam cadastrados em alguma turma.

Padrão ANSI-SQL

SELECT a.*, b.*

  FROM aluno a

  INNER JOIN turma b ON b.cod_turma = a.cod_turma;



Query no padrão Tradicional

SELECT a.*, b.*

  FROM aluno a

      ,turma b

 WHERE a.cod_turma = b.cod_turma;


* LEFT JOIN

Este tipo de JOIN pode ser utilizado quando queremos recuperar os dados da primeira tabela, mesmo se não houver dado correspondente na segunda tabela.

Padrão ANSI-SQL

SELECT a.*, b.*

  FROM aluno a

  LEFT JOIN turma b ON b.cod_turma = a.cod_turma;

Repare que a query retornou todos os registros da tabela 1(aluno), independente da ligação com a tabela 2(Turma).


Query no padrão Tradicional

SELECT a.*, b.*

  FROM aluno a

      ,turma b

 WHERE a.cod_turma = b.cod_turma(+)  

  

* RIGHT JOIN

Este tipo de JOIN pode ser utilizado quando queremos recuperar os dados da segunda tabela, mesmo se não houver dado correspondente na primeira tabela.

Padrão ANSI-SQL

SELECT a.*, b.*

  FROM aluno a

  RIGHT JOIN turma b ON b.cod_turma = a.cod_turma;


Repare a query retornou todos os registros da tabela 2(Turma), independente da ligação com a tabela 2(Turma)


Query no padrão Tradicional

SELECT a.*, b.*

  FROM aluno a

      ,turma b

 WHERE a.cod_turma(+) = b.cod_turma


* FULL JOIN

Neste caso juntos o INNER JOIN mais as linhas sem associação, tanto do lado direto(RIGHT JOIN), quanto do lado esquerdo(LEFT JOIN), não sendo possível utilizar nenhum filtro nas tabelas, ex1, caso seja necessário utilização de algum filtro será necessário executar um sub-select, ex2.

Obs: Esse tipo JOIN não tem suporte no padrão tradicional.

Ex1

SELECT a.*, b.*

  FROM aluno a

  FULL JOIN turma b ON b.cod_turma = a.cod_turma;


Ex2 - Filtrei apenas os alunos c/ código de turma preenchido.

SELECT a.*, b.*

  FROM (SELECT * 

          FROM aluno aa

         WHERE aa.cod_turma IS NOT NULL) a

  FULL JOIN turma b ON b.cod_turma = a.cod_turma;  


* CROSS JOIN

Pode ser utilizado quando for necessária a junção de duas ou mais tabelas por cruzamento, esse tipo de JOIN também é conhecido como produto cartesiano entre duas tabelas.

SELECT a.*, b.* FROM aluno a CROSS JOIN turma b 

ORDER BY a.cod_aluno, b.cod_turma;

Coloquei um order by na query pra evidenciar bem os dados repetidos (Produto Cartesiano)


Query no padrão Tradicional

SELECT a.*, b.* FROM aluno a, turma b 


É isso, pessoal. Espero que tenham gostado e até a próxima.

Abs.

Leonardo Silva.





Um comentário:

Estudando para o exame de certificação Oracle Database SQL | 1Z0-071 - Comando Merge

Fala, galera. Tudo bem? Hoje vou falar um pouco sobre o comando MERGE. O MERGE é um comando DML que combina as funções de insert, update e d...