Home - www.devmedia.com.br

Explorando os Tipos de Join – Parte II

Olá !

Com o auxílio da figura-1 listada a seguir e, à partir do script para criação das tabelas produto (cod_ produto , descr_ produto ) e venda (cod_ produto , qtde, vlr_unit) forcecido na matéria anterior (Explorando os tipos de Join  – Parte I)  ...


... vamos praticar a execução diferentes tipos de join para responder as questões a seguir :

  1. Listar os produtos que foram vendidos e possuem cadastro

    A resposta está na interseção entre produto e venda , representado na figura-1 pela cor verde . Será resolvido com um inner join :

    select produtos_vendidos_com_cadastro = p.cod_produto
    from produto p
    inner join
        venda v
    on p.cod_produto = v.cod_produto
    --------------------------------------------------------------------------------------------------------------------------------------------
    produtos_vendidos_com_cadastro
    -----------------------------------------------
    101001
    101002
    101003
    (3 row(s) affected)

  2. Listar os produtos que foram vendidos sem cadastro

    Deveremos resgatar os produtos da área em azul , que não possuem correspondência na tabela produto . Será utilizado um right join para selecionar todas as linhas da tabela venda ;  o filtro .... ... where p.cod_ produto is null nos permitirá filtrar somente as vendas de produtos sem cadastro :

    select produtos_vendidos_sem_cadastro = v.cod_produto
    from produto p
    right outer join
          venda v
    on v.cod_produto = p.cod_produto
    where p.cod_ produto IS NULL
    -------------------------------------------------------------------------------------------------------------------------------------------
    produtos_vendidos_sem_cadastro
    -----------------------------------------------
    101030
    101031
    (2 row(s) affected)

  3. Listar os produto com cadastro que NÃO foram vendidos

    A resposta para essa pergunta está na área em vermelho da figura-1. Para sua resolução foi empregado um left join , mas o mesmo resultado poderia ser obtido com um right join , bastando para isso inverter a ordem das tabelas   ... from venda v right outer join  produto p on ....

    select produtos_com_cadastro_sem_venda = p.cod_produto
    from produto p
    left outer join
          venda v
    on v.cod_produto = p.cod_produto
    where v.cod_produto IS NULL

    produtos_com_cadastro_sem_venda
    -------------------------------
    101004
    101005

    (2 row(s) affected)

    Algumas dicas interessantes : 

    Left Join irá listar todas as linhas da primeira tabela relacionada no join, logo após a cláusula from.

    Right Join irá listar todas as linhas referentes à segunda tabela relacionada no join ;

    Em ambos os casos , quando a linha listada não possuir equivalência na tabela destino , as colunas da tabela destino   aparecerão com valores nulos

  4. Formule um join para responder às questões abaixo

    Quais foram os produtos vendidos que possuiam cadastro ;
    Quais foram os produtos vendidos que não possuiam cadastro ;
    Quais foram os produtos com cadastro que não foram vendidos

    Além do código do produto , liste também sua descrição ( produtos sem cadastro deverão aparecer com a descrição “ sem cadastro ”) e, numa coluna de nome observacao , informe uma das três possibilidades: venda com cadastro (= item a),  venda sem cadastro (= item b) ou produto com cadastro sem venda (= item c)

    select produto        = case when p.cod_ produto    is     nul
                                              then v.cod_ produto
                                              else p.cod_ produto
                                     end,
              descricao    = case when p.descr_ produto is NOT null
                                              then p.descr_produto
                                              else 'sem cadastro'
                                     end,
              observacao = case when p.cod_ produto    is NOT null  and v.cod_ produto    is NOT null
    then 'venda com cadastro'
                                              when p.cod_ produto    is NOT null  and v.cod_ produto    is  null
                                             then 'produto com cadastro sem venda'
                                             else 'produto sem cadastro com venda'
                                     end
    from produto p
    full outer join
         venda v
    on p.cod_ produto = v.cod_ produto
    ------------------------------------------------------------------------------------------------------------------------------------------- produto     descricao             observacao                  

    ----------- --------------------       ------------------------------ 101001      Livro-1                venda com cadastro
    101002      Livro-2                venda com cadastro
    101003      Livro-3                venda com cadastro
    101004      Livro-4                produto com cadastro sem venda
    101005      Livro-5                produto com cadastro sem venda
    101030      sem cadastro     produto sem cadastro com venda
    101031      sem cadastro     produto sem cadastro com venda
    (7 row(s) affected)

E o CROSS JOIN ?

O cross join irá relacionar todos os elementos da primeira tabela com todos os elementos da segunda tabela ; num movimento conhecido por Produto Cartesiano. Pode ser que você nunca precise utilizar esse tipo de join,  mas é bom saber que existe e, em que situações poderia ser utilizado.

Vamos supor que você possua uma tabela com siglas das unidades da federação . Você quer emitir uma listagem onde os produtos apareçam ao lado de cada sigla da federação . A tabela de unidades da federação e o select para produzir o relatório encontram-se listados a seguir .

/* criação da tabela uf */
create table uf ( sigla char(2))
insert into uf values ('SP')
insert into uf values ('RJ')

/* select com o Produto Cartesiano entre a tabela produto e uf */
select *
from produto
cross join uf
-------------------------------------------------------------------------------
------------------------------------------------------------
cod_produto      descr_produto    sigla
-----------------       --------------------      ------
101001              Livro-1                SP
101002              Livro-2                SP
101003              Livro-3                SP
101004              Livro-4                SP
101005              Livro-5                SP
101001              Livro-1                RJ
101002              Livro-2                RJ
101003              Livro-3                RJ
101004              Livro-4                RJ
101005              Livro-5                RJ
(10 row(s) affected)

Conclusão

Antes de escolher o tipo de join para sua query, visualize o que realmente você deseja . Conhecer os tipos de join existentes para utilizá-los quando a situação exige pode ser a diferença entre o certo e o errado, o rápido e o lento .

Um forte abraço a todos

Bem pessoal, por hoje é só.

Até a próxima!

 

Paulo Ribeiro (psribeiro@hotmail.com) é Microsoft MCDBA e membro da equipe editorial da SQL Magazine. Atua como DBA sênior em SQL Server na Livraria e Papelaria Saraiva S/A.

  Monitorando deadlocks com Trace Flags    
  Monitorando deadlocks com o Profiler    
  Variáveis tipo TABLE    
  Tabelas Temporárias    
  Subqueries Parte II: Queries correlatas    
  Subqueries – Parte I    
  Gerenciando Bloqueios–Parte II    
  Gerenciando Bloqueios–Parte I    
  Porque qualificar o owner na chamada de stored-procedures    
  Explorando os Tipos de Join – Parte II    
  Explorando os Tipos de Join – Parte I    
  Versões existentes do SQL Server 2000    
  Tuning - Plano de Execução no SQL Server - Parte 4    
  Tuning - Plano de Execução no SQL Server - Parte 3    
  Tuning - Plano de Execução no SQL Server - Parte 2    
  Tuning - Plano de Execução no SQL Server - Parte 1    
  Tuning - Estatísticas de I/O    
  Desfragmentando Índices no SQL Server    
  Procedures Não Documentadas
no SQL Server 2000 Parte 2
   
  Procedures Não Documentadas
no SQL Server 2000.
   
  SQL Server 2005 - YUKON    
  SQL Server 2000: o Contra-Ataque.    
  Boas-Vindas    
     

 

Todos os direitos reservados: DevMedia Group
SQL Magazine - 2004