COMO FAZER RELATÓRIO DE COMPRA E VENDA
Como buscar entrada e saída de produto por um período com sql?
Para isso é usado principalmente UNION e GROUP BY assim:
Segue abaixo um exemplo de consulta por entrada e saída de produtos. Primeiro é feito a query depois comentado.SELECT
#Aqui é iniciado a camada externa do select usada para agrupar os dois select do union
cod_barra, descricao, pmc, grupo, preco,
#Passados algumas variáveis referente ao produto
SUM(quant_venda) as quant_venda,
#Soma da quantidade de venda
sum(vlr_venda) as vlr_venda,
#Soma do valor de venda
SUM(total_venda) as total_venda,
#Soma do total de venda
SUM(quant_compra) as quant_compra,
#Soma da quantidade de compra
sum(vlr_compra) as vlr_compra,
#Soma do valor de compra
SUM(total_compra) as total_compra
#Soma do total de compra
from (
#Referencia os agrupamentos e unions nos dois selects de compra e venda
select
#inicio do primpeiro select referente a venda
p.cod_barra, p.descricao, p.pmc, p.grupo, p.preco,
#Passadas as variáveis igual ao geral e as vendas
round(sum(vp.quantid), 0) as quant_venda,
#Soma da quantidade de venda igual a geral e usado a função ROUND para formatar o número e colocar zero caso não tenha valor
ROUND(sum(vp.vlr_item) / sum(vp.quantid), 2) AS vlr_venda,
#Soma do valor de venda igual a geral e usado a função ROUND para formatar o número e colocar duas casas decimais no número
ROUND(sum(vp.vlr_item), 2) AS total_venda,
#Soma do total de venda igual a geral e usado a função ROUND para formatar o número e colocar duas casas decimais
null as quant_compra, null as vlr_compra, null as total_compra
#Passadas as variáveis nulas para completar a tabela do UNION
from produto p
#Referencia a tabela de produtos
inner join vendas_item vp on (vp.cod_barras = p.cod_barra)
#Vincula a tabela de produto com a tabela de item das vendas
inner join vendas_cab v on (v.numero = vp.numero and
#Vincula a tabela de itens de venda com o cabeçalho de vendas
v.data >= :data_ini and
#Usa a data para limitar o join, poderia ser feito com where também
v.data <= :data_fim)
#Mesmo que a outra data, mas uma inicial e outra final
group by p.cod_barra, p.descricao
#Agrupa por código de barra e descrição, para alguns bancos é necessário os dois
union
#Faz o UNION dos dois select
select
#Inicia o select para compra igual o da venda
p.cod_barra, p.descricao,p.pmc, p.grupo, p.preco,
#variáveis de produto...
null as quant_venda, null as vlr_venda, null as total_venda,
#Variáveis com valores null para equilibrar a tabela
round(sum(cp.quantid), 0) as quant_compra,
ROUND(sum(cp.vlr_prod) / sum(cp.quantid), 2) AS vlr_compra,
ROUND(sum(cp.vlr_prod), 2) AS total_compra
from produto p
inner join compra_itens cp on (cp.cod_ean = p.cod_barra)
inner join compra_cab c on (c.numero = cp.numero and
c.data_lct >= :data_ini and
c.data_lct <= :data_fim )
group by p.cod_barra, p.descricao
) as geral
group by cod_barra, descricao, pmc, grupo, preco
#Agrupa os selects de compra e venda
Este é um exemplo de agrupamento de entrada e saída de produto, ela dá um norte e pode ser completada com outras tabelas como fornecedor ou clientes.
Foi solicitado fazer um comparativo entre as vendas e as compras de produtos por período, mas usando apenas joins ele duplicava as linhas e multiplicava os valores, usando subqueries ou seja select dentro de select a consulta ficava muito lenta, por isso foi usado UNION com agrupamentos.