Showing posts with label right join. Show all posts
Showing posts with label right join. Show all posts

Wednesday, February 24, 2010

Oracle SQL - Usando LEFT and RIGHT JOIN

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