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 :
- 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)
-
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)
- 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
-
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. |
|
|
|
|