Olá,
Hoje o assunto é OUTER JOIN.
Essa dica de post eu peguei com o meu amigo Eduardo do blog bieduardo.blogspot.com/ .
Normalmente muitos profissionais caem nesta dúvida cruel.
Como fazer corretamente um OUTER JOIN?
Pirmeiro vamos relembrar o que é um OUTER JOIN.
"Um OUTER JOIN é um SIMPLE JOIN ou INNER JOIN com uma "opção extendida " de trazer também os dados que não satisfazem a condição de JOIN.
No Oracle para usar LEFT ou RIGHT OUTER JOIN em seu SQL você pode usar o caracter "+" entre parênteses para informar ao Oracle qual operador você está utilizando.Você também pode usar o padrão SQL92 para JOIN usando as palavras RIGHT OUTER JOIN e LEFT OUTER JOIN.
Mostrarei isso mais a frente no segundo post.
A explicação sobre de qual lado utilizar é simples:
Se a coluna que contém os dados nulos é a da direita você então coloca o sinal (+) na coluna da esquerda e vice-versa.
Ex. Nas tabelas A e B existe a coluna ID do tipo NUMBER.
Na tabela A existe uma linha em que a coluna ID é nula,mas mesmo assim você precisa trazer esta linha na sua query ,neste caso você precisar fazer um JOIN para obtê - las.
ex.
select
from tabela1 A,tabela2 B
where A.id = B.id(+) ;
No exemplo acima foi feito um LEFT JOIN pois quero retornar todos os dados da tabela A que não satisfazem a condição da JOIN .
Criando as tabelas de exemplo :
dbajcc@DBPOST on 23-FEB-10 >create table jcc_join_a (seq number(2) , text varchar2(10)) ; 2 3 Table created. Elapsed: 00:00:00.03 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_a values(1,'disk1') ; 2 1 row created. Elapsed: 00:00:00.02 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_a values(2,'disk2') ; 2 1 row created. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_a(seq) values(3) ; 2 1 row created. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 >commit ; Commit complete. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 > create table jcc_join_b (seq number(2) , text varchar2(10)) ; 2 3 Table created. Elapsed: 00:00:00.02 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_b values(1,'disk1') ; 2 1 row created. Elapsed: 00:00:00.01 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_b values(2,'disk2') ; 2 1 row created. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_b(text) values('disk3') ; 2 1 row created. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 > |
Fazendo um RIGHT JOIN :
dbajcc@DBPOST on 23-FEB-10 >select a.* ,b.* from jcc_join_a a, jcc_join_b b where a.seq(+) = b.seq ; 2 3 4 SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 disk3 Elapsed: 00:00:00.02 dbajcc@DBPOST on 23-FEB-10 > |
Ou usando a sintaxe do padrão SQL92 :
dbajcc@DBPOST on 24-FEB-10 >select a.* ,b.* 2 from jcc_join_a a right outer join jcc_join_b b 3 on a.seq = b.seq ; SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 disk3 Elapsed: 00:00:00.00 dbajcc@DBPOST on 24-FEB-10 > |
Acima destaquei em azul a coluna na qual é o alvo e que por sinal contém um campo SEQ nulo para o campo TEXT "disk3" .
Agora vamos fazer um LEFT JOIN :
[oracle@marte ~]$ sqlplus dbajcc SQL*Plus: Release 11.2.0.1.0 Production on Wed Feb 24 07:49:02 2010 Copyright (c) 1982, 2009, Oracle. All rights reserved. Enter password: Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options dbajcc@DBPOST on 24-FEB-10 > select a.* ,b.* from jcc_join_a a, jcc_join_b b where a.seq = b.seq(+) ; 2 3 4 SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 3 Elapsed: 00:00:00.05 dbajcc@DBPOST on 24-FEB-10 > |
Ou usando o outro tipo de sintaxe :
dbajcc@DBPOST on 24-FEB-10 >select a.* ,b.* 2 from jcc_join_a a left outer join jcc_join_b b 3 on a.seq = b.seq ; SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 3 Elapsed: 00:00:00.19 dbajcc@DBPOST on 24-FEB-10 > |
Temos uma outra opção que é usar a um FULL OUTER JOIN para trazer os dados que não satisfazem a condição de JOIN das duas tabelas envolvidas.
dbajcc@DBPOST on 24-FEB-10 >select a.* ,b.* 2 from jcc_join_a a full outer join jcc_join_b b 3 on a.seq = b.seq ; SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 disk3 3 Elapsed: 00:00:00.01 dbajcc@DBPOST on 24-FEB-10 > |
Nem vou trazer exemplos sobre Cartesian Join pois acredito ser de pouca utilidade.
Até,
Júlio César Corrêa
2 comments:
Olá Júlio,
Excelente post. Aliás, seu blog está ótimo!
Abraços,
Eduardo Legatti
Olá Eduardo,
Muito obrigado por passar por aqui!
Vamos aprendendo dia após dia.
Ainda tenho muito que apreder a postar artigos com vocês mestres!
Post a Comment