SQL para movimentação de Estoque

Firebird

01/06/2012

Olá Amigos,

To com o seguinte problema, preciso fazer uma pesquisa que me mostre a movimentação do estoque em determinado período. Tenho as seguintes tabelas (declarei somente os campos relevantes abaixo):

Produtos (Cod_Produto, Descricao);
Vendas(Cod_Venda, Data, Total);
Vendas_Prod (Cod_Produto,Cod_Venda Quant, Valor_unit, total);
Compra (Cod_Compra, Data, Total);
Compras_Prod (Cod_Produto,Cod_compra Quant, Valor_unit, total);

Quero saber como montar uma só consulta SQL para saber a quantidade total de produtos vendidos e comprados em determinado periodo:
Ex:

Cod. Descricao Quant_Venda Quant_Compra
01 Coca Cola 100 120
02 Sprite 56 80



Se alguém puder ajudar, ficarei muito grato.

Daniel Pessoa

Daniel Pessoa

Curtidas 0

Melhor post

Emerson Nascimento

Emerson Nascimento

07/06/2012

select 
  p.Codigo2, p.descprod,
  coalesce(sum(v.Quant),0) as Quant_Venda,
  coalesce(sum(c.Quant),0) as Quant_Compra,
  coalesce(sum(c.Quant),0) - coalesce(sum(v.Quant),0) as Saldo
from Produtos p
left join ProdVenda vp on vp.Cod_Produto = p.Codigo2
left join Venda v on v.Cod_Venda = vp.Cod_Venda and v.Datav between :DataIni and :DataFim
left join ProdCompra cp on cp.Cod_Produto = p.Codigo2
left join Compra c on c.Cod_Compra = cp.Cod_Compra and c.Datac between :DataIni and :DataFim
group by p.Codigo2, p.descprod
having (coalesce(sum(v.Quant),0) + coalesce(sum(c.Quant),0)) > 0
GOSTEI 2

Mais Respostas

Bruno Leandro

Bruno Leandro

01/06/2012

Ola daniel, tente o comando a baixo

select
p.Cod_Produto,
p.Descricao,
( select sum( x.Quant ) from Vendas_Prod x inner join Vendas x1 on x1.Cod_Venda = x.Cod_Venda where x.Cod_Produto = p.Cod_Produto and x1.Data between :data1 and :data2 ) as qtd_venda,
( select sum( y.Quant ) from Compras_Prod y inner join Compras y1 on y1.Cod_compra = y.Cod_compra where y.Cod_Produto = p.Cod_Produto and y1.Data between :data1 and :data2 ) as qtd_compra
from produtos p
GOSTEI 0
Daniel Pessoa

Daniel Pessoa

01/06/2012

Obrigado Bruno,

A consulta SQL funcionou, porém só tem um problema. Este código busca todos os produtos, mesmo aqueles que não tiverem movimentação no período, aí demora uns 5 minutos pra executar. Tem como filtrar só aqueles com quantidade_venda ou quantidade_compra >0?
GOSTEI 0
Daniel Pessoa

Daniel Pessoa

01/06/2012

Tentei fazer uma abordagem um pouco diferente. O resultado está perto do que preciso. As tabelas estão assim (declarei somente os campos relevantes abaixo):

Venda(Cod_Venda, Datav, Total);
ProdVenda (Cod_Produto, Produto, Cod_Venda, Quant, Valor_unit, totalprod);
Compra (Cod_Compra, Datac, Total);
ProdCompra (Cod_Produto, Produto,Cod_compra, Quant, Valor_unit, totalprod);

Criei a consulta da seguinte maneira:

select PV.Cod_Produto, PV.Produto, sum(PV.Quant) as qtd_venda, sum(PV.TotalProd) as totalvenda from ProdVenda PV where PV.Cod_Venda in(select Cod_Venda from Venda V where V.Datav between :DataIni and :DataFim)

e outra assim:

select PC.Cod_Produto, PC.Produto, sum(PC.Quant) as qtd_compra, sum(PC.TotalProd) as totalcompra from ProdCompra PC where PC.Cod_Compra in(select Cod_Compra from Compra C where C.Datac between :DataIni and :DataFim)

as duas funcionam bem e de forma rápida, porém preciso juntar as 2 consulta numa só IBQuery de forma que tenha a movimentação tanto de venda quanto de compra na mesma linha do QuickReport.

Além disso, é possível dentro do SQL, efetuar o cálculo de saldo de movimentação e lucro no período baseado em cada produto, tipo:

lucro = PV.TotalProd - PC.TotalProd

???

Espero que alguém possa ajudar, obrigado
GOSTEI 0
Bruno Leandro

Bruno Leandro

01/06/2012

Ola daniel a minha ideia é a seguinte indices, existem algum indice criado nestas tabelas caso nao tente assim

um indice para a tabela de vendas
create index ix1_vendas on vendas computed by (Cod_Venda,Datav);

e talvez um ou dois para a tabela ProdVenda
create index ix1_ProdVenda on ProdVenda computed by (Cod_Produto,Cod_Venda);
create index ix2_ProdVenda on ProdVenda computed by (Cod_Venda,Cod_Produto);


um indice para a tabela de Compra
create index ix1_Compra on Compra computed by (Cod_Compraa,Datac);

e talvez um ou dois para a tabela ProdCompra
create index ix1_ProdCompra on ProdCompra computed by (Cod_Produto,Cod_compra);
create index ix2_ProdCompra on ProdCompra computed by (Cod_compra,Cod_Produto);


ai voce pega o comando que passei e cria uma view como ele
ai voce usa o comando assim

select * from view_movimentacao_estoque
where qtd_venda > 0 or qtd_compra > 0

GOSTEI 0
Daniel Pessoa

Daniel Pessoa

01/06/2012

eu crio esses indices no banco pelo interbase, ou pode ser pelo Delphi em modo de execução?
GOSTEI 0
Bruno Leandro

Bruno Leandro

01/06/2012

no banco de dados, similar ao criar campos, tabelas e outros objetos do banco
GOSTEI 0
Daniel Pessoa

Daniel Pessoa

01/06/2012

Obrigado pessoal pelas dicas, agora consegui resolver do jeito que precisava e ficou rápida a consulta e só mostrou produtos que tiveram compra ou venda. Ficou assim:

select p.Codigo2, p.descprod, v.Quant as Quant_Venda, c.Quant as Quant_Compra from Produtos p
right join (select vp.Cod_Produto, sum(vp.Quant) as Quant, from ProdVenda vp join Venda v on vp.Cod_Venda = v.Cod_Venda where v.Datav between :DataIni and :DataFim group by vp.Cod_Produto having sum(vp.Quant) > 0) v on v.Cod_Produto = p.Codigo2 full join (select cp.Cod_Produto, sum(cp.Quant) as Quant from ProdCompra cp
join Compra c on cp.Cod_Compra = c.Cod_Compra where c.Datac between :DataIni and :DataFim group by cp.Cod_Produto having sum(cp.Quant) > 0) c on c.Cod_Produto = p.Codigo2

Mas só pra complicar mais um pouco, tem como adicionar um cálculo de saldo e/ou lucro a esta sql, tipo:

saldo = c.Quant - v.Quant
GOSTEI 0
POSTAR