Sub-query correlata e ordinaria

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
Mr.Paulo
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Dom, 03 Jun 2007 9:07 pm
Localização: Barretos-SP

Pessoal,

alguém tem alguma apostila ou tutorial sobre sub-query correlatas e ordinarias !?!?!

Obrigado
Hahu
Rank: Analista Sênior
Rank: Analista Sênior
Mensagens: 147
Registrado em: Qui, 16 Mar 2006 11:26 am
Localização: São Paulo
O mundo gira muito!!

Fala Mr.Paulo,
Boa tarde amigo,

Segue as informações:
Subqueries Parte II: Queries correlatas

No artigo anterior – Subqueries Parte I – vimos que uma subquery é um comando SELECT que foi "embutido" noutro comando SELECT, UPDATE, DELETE ou dentro de outra subquery. Vimos também que a finalidade da subquery é retornar um conjunto de linhas para a query principal.

Subqueries Correlatas

Quando uma subquery referencia colunas da query principal, recebe o nome de Subquery Correlata.

Diferentemente das subqueries convencionais, a Subquery Correlata será executada tantas vezes quantas forem as linhas de output da query principal, num processo de Nested Loop Join.

Exemplos de utilização de Subqueries Correlatas

Os exemplos a seguir foram executados no database-exemplo NorthWind tendo por base as tabelas Orders e Order Details.

· Subquery Correlata na linha do SELECT: na query a seguir será listado, junto com os dados da header do pedido (=tabela Orders), a totalização de itens (=tabela Order Details).

PS: Note a relação de dependência com a query principal no filtro da subquery (... where od.orderId = o.orderId ...)

Selecionar tudo

SELECT
  customerId,
  orderId,
  qtde_itens_orderId = (select sum(quantity) from [order details] od     whereod.orderId = o.orderId )
from Orders o
---------------------------------------------------------------------

customerId orderId     qtde_itens_orderId 
---------- ----------- ------------------ 
ALFKI         10643          38
ALFKI         10692          20
ALFKI         10702          21
ALFKI         10835          17
ALFKI         10952          18
ALFKI         11011          60
ANATR        10308          6
ANATR        10625          18
ANATR        10759          10
.
...
.....

· Subquery Correlata no filtro WHERE: serão listados somente os pedidos cuja quantidade total de itens supere 250 unidades.

Selecionar tudo

SELECT
  customerId,
  orderId,
  qtde_itens_orderId = (select sum(quantity) from [order details] od     where
od.orderId = o.orderId )
from Orders owhere (select sum(quantity) from [order details] od   where od.orderId = o.orderId ) > 250
order by 3
---------------------------------------------------------------------

Selecionar tudo



customerId   orderId     qtde_itens_orderId
---------- ----------- ------------------
QUICK          10658          255
ERNSH         10990           256
SAVEA         10612          263
SAVEA         10678          280
QUICK          10515          286
SAVEA         10847          288
SAVEA         11030          330
ERNSH         10895          346

(8 row(s) affected)


· Subquery Correlata na cáusula HAVING: no batch a seguir o total de vendas/ano é confrontado com um valor previamente armazenado numa tabela de metas de venda (=projecao). Note que a comparação acontece na cláusule HAVING, comparando o totalizador com o resultado da subquery.

Selecionar tudo


create table projecao_
( 
  ano int,
  vlr_total_vendas dec(10,2)
)
insert into projecao_values (1996,250000)
insert into projecao_values (1997,630000)
insert into projecao_values (1998,500000)
select Ano=year(orderdate), vlr_total_vendas=sum(unitprice *   quantity)
from orders o
inner join
     [order details] od
on o.orderId = od.orderId
group by year(orderdate)
having sum(unitprice * quantity) >= 

        ( select vlr_total_vendas from projecao_where
               ano=year(orderdate) )
---------------------------------------------------------------------
   Ano            vlr_total_vendas      
----------- --------------------- 
1997           658388.7500
(1 row(s) affected)

· Subquery Correlata no comando UPDATE: a coluna vlr_total, criada na tabela Orders será atualizada a partir da totalização dos itens.

Selecionar tudo


alter table orders drop column vlr_total
go
alter table orders add vlr_total dec(10,2) 
go
update orders 
   set vlr_total=
   ( select sum(unitprice * quantity) 
     from [order details] od 
     where od.OrderId = orders.orderId 
     group by od.orderId 
   )
go

--------------------------------------------------------------------(830 row(s) affected)

Conclusão

Subqueries correlatas agregam versatilidade às queries, permitindo que joins complexos sejam resolvidos com apenas um comando, sem a criação de tabelas temporárias. Um único detalhe: subqueries correlatas muitas vezes podem ser executadas como um join convencional; nesses casos vale a pena olhar o plano de execução dos dois formatos (subquery correlata X join), optando pelo mais eficiente.

Bem, essa foi a dica de hoje.

Até a próxima!

Leia a primeira parte deste artigo em:
http://www.devmedia.com.br/articles/vie ... ?comp=2835

Qualquer duvida , posta aqui no forum..

Abs de seu amigo Hahu :) -m
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 16 visitantes