Select dentro de Select com Sum
Ola, Estou com um pequeno problema. Preciso que Retorne em uma Consulta a seguinte linha:
Produto Estoque Qtd Vendido Qtd Comprado
TESTE 8 2 10
Tabelas:
Itens Venda (ID Venda, ID Produto, Quantidade)
Venda (ID Venda, Emissao)
Estoque (ID Produto, Disponivel)
Produto (ID Produto, Nome)
Movimento(ID Produto, Data, Quantidade, Tipo).
** Firebird 2.0 - SQL:
select produto.nome as PRODUTO,
estoque.disponivel as DISPONIVEL,
sum(Itens_Venda.quantidade)as VENDIDO,
sum(movimento.quantidade) as COMPRADO
from itens_venda, Venda, produto, estoque
join movimento on movimento.ID_PRODUTO = produto.ID_produto
and movimento.TIPO = 2 -- ENTRADA
and movimento.ID_PRODUTO = Itens_Venda.ID_PRODUTO
and movimento.DATA >= :Data1 and movimento.DATA <= :Data2
where Venda.ID_VENDA = Itens_Venda.ID_VENDA
and Venda.EMISSAO >= :Data1 and Venda.EMISSAO <= :Data2
and produto.ID_PRODUTO = Itens_venda.ID_PRODUTO
and Produto.ID_PRODUTO = estoque.ID_PRODUTO
and estoque.ID_PRODUTO = Itens_Venda.ID_PRODUTO
group produto.nome, estoque.disponivel
O que acontece e o seguinte...
Na Tabela de Movimento, eu tenho 2 registros pra este produto, pois foi dado entrada 2 vezes na mesma data.
Quando mostra o resultado ele esta dobrando o valor no campo vendido. Deveria aparecer 2 unidades e ele mostra 4.
Entao ele esta passando pela quantidade de registros e dobrando o valor.
Na Tabela Itens_Venda existe somete 1 registro, quando tem outras vendas ele altera o COMPRADO.
Ja tentei varios codigos , com Join e sem.
Infelizmente ainda nao encontrei nada parecido. Espero que alguem de uma forca ai.
Produto Estoque Qtd Vendido Qtd Comprado
TESTE 8 2 10
Tabelas:
Itens Venda (ID Venda, ID Produto, Quantidade)
Venda (ID Venda, Emissao)
Estoque (ID Produto, Disponivel)
Produto (ID Produto, Nome)
Movimento(ID Produto, Data, Quantidade, Tipo).
** Firebird 2.0 - SQL:
select produto.nome as PRODUTO,
estoque.disponivel as DISPONIVEL,
sum(Itens_Venda.quantidade)as VENDIDO,
sum(movimento.quantidade) as COMPRADO
from itens_venda, Venda, produto, estoque
join movimento on movimento.ID_PRODUTO = produto.ID_produto
and movimento.TIPO = 2 -- ENTRADA
and movimento.ID_PRODUTO = Itens_Venda.ID_PRODUTO
and movimento.DATA >= :Data1 and movimento.DATA <= :Data2
where Venda.ID_VENDA = Itens_Venda.ID_VENDA
and Venda.EMISSAO >= :Data1 and Venda.EMISSAO <= :Data2
and produto.ID_PRODUTO = Itens_venda.ID_PRODUTO
and Produto.ID_PRODUTO = estoque.ID_PRODUTO
and estoque.ID_PRODUTO = Itens_Venda.ID_PRODUTO
group produto.nome, estoque.disponivel
O que acontece e o seguinte...
Na Tabela de Movimento, eu tenho 2 registros pra este produto, pois foi dado entrada 2 vezes na mesma data.
Quando mostra o resultado ele esta dobrando o valor no campo vendido. Deveria aparecer 2 unidades e ele mostra 4.
Entao ele esta passando pela quantidade de registros e dobrando o valor.
Na Tabela Itens_Venda existe somete 1 registro, quando tem outras vendas ele altera o COMPRADO.
Ja tentei varios codigos , com Join e sem.
Infelizmente ainda nao encontrei nada parecido. Espero que alguem de uma forca ai.
Fernando Coelho
Curtidas 0
Respostas
Misterzire
27/06/2016
Tenta incluir um distinct na sua clausula select.
GOSTEI 0
Fernando Coelho
27/06/2016
Ja tinha tentado... achei uma forma , pode ser util pra alguem
create or alter procedure REL_VENDAS1 (
EMP001 integer,
DATA_INI date,
DATA_FIN date,
EST_PROSUB integer,
CMP_FOR001 integer)
returns (
NOME varchar(60),
PRO001 integer,
EST_PROSUB_NOME varchar(30),
CMP_FOR001_NOME varchar(60),
QTDADE_VENDA numeric(10,2),
QTDADE_COMPRA numeric(10,2),
QTDADE_ESTOQUE numeric(10,2))
as
declare variable VSQL varchar(1000);
begin
vsql = 'select distinct est_pro001.pro001, est_pro001.nome as PRODUTO, est_prosub.nome as SUBGRUPO, CMP_FOR001.nome as FORNECEDOR,est_saldos.disponivel from est_pro001, est_saldos, est_prosub, cmp_for001';
vsql = vsql || ' where est_saldos.pro001 = est_pro001.pro001 and est_saldos.emp001 = '''||:emp001||'''';
vsql = vsql || ' and est_prosub.prosub = est_pro001.est_prosub';
vsql = vsql || ' and cmp_for001.for001 = est_pro001.cmp_for001';
if(:est_prosub > 0) then
vsql = vsql || ' and est_pro001.est_prosub = ''' ||:est_prosub||'''';
if(:cmp_for001 > 0) then
vsql = vsql || ' and est_pro001.cmp_for001 = ''' ||:cmp_for001||'''';
if(:est_prosub > 0) then
vsql = vsql || ' order by est_prosub.nome, cmp_for001.nome, est_pro001.pro001';
else if(:cmp_for001 > 0) then
vsql = vsql || ' order by cmp_for001.nome, est_prosub.nome, est_pro001.pro001';
else
vsql = vsql || ' order by cmp_for001.nome, est_prosub.nome, est_pro001.pro001';
for
execute statement vsql
into :pro001, :nome, :est_prosub_nome, :cmp_for001_nome, :qtdade_estoque
do begin
for select coalesce(sum(vda_vda002.quantidade),0) as VENDIDO
from vda_vda002, vda_vda001
where vda_vda002.pro001 = :pro001
and vda_vda002.vda001 = vda_vda001.vda001
and vda_vda002.emp001 = vda_vda001.emp001
and vda_vda001.emissao >= :data_ini and vda_vda001.emissao <= :data_fin
and vda_vda001.emp001 = :emp001
into :qtdade_venda
do begin
for select coalesce(sum(est_promov.quantidade),0) as COMPRADO
from est_promov
where est_promov.pro001 = :pro001
and est_promov.data >= :data_ini and est_promov.data <= :data_fin
and est_promov.prohis = 2
and est_promov.emp001 = :emp001
into :qtdade_compra
do
suspend;
end
end
end
create or alter procedure REL_VENDAS1 (
EMP001 integer,
DATA_INI date,
DATA_FIN date,
EST_PROSUB integer,
CMP_FOR001 integer)
returns (
NOME varchar(60),
PRO001 integer,
EST_PROSUB_NOME varchar(30),
CMP_FOR001_NOME varchar(60),
QTDADE_VENDA numeric(10,2),
QTDADE_COMPRA numeric(10,2),
QTDADE_ESTOQUE numeric(10,2))
as
declare variable VSQL varchar(1000);
begin
vsql = 'select distinct est_pro001.pro001, est_pro001.nome as PRODUTO, est_prosub.nome as SUBGRUPO, CMP_FOR001.nome as FORNECEDOR,est_saldos.disponivel from est_pro001, est_saldos, est_prosub, cmp_for001';
vsql = vsql || ' where est_saldos.pro001 = est_pro001.pro001 and est_saldos.emp001 = '''||:emp001||'''';
vsql = vsql || ' and est_prosub.prosub = est_pro001.est_prosub';
vsql = vsql || ' and cmp_for001.for001 = est_pro001.cmp_for001';
if(:est_prosub > 0) then
vsql = vsql || ' and est_pro001.est_prosub = ''' ||:est_prosub||'''';
if(:cmp_for001 > 0) then
vsql = vsql || ' and est_pro001.cmp_for001 = ''' ||:cmp_for001||'''';
if(:est_prosub > 0) then
vsql = vsql || ' order by est_prosub.nome, cmp_for001.nome, est_pro001.pro001';
else if(:cmp_for001 > 0) then
vsql = vsql || ' order by cmp_for001.nome, est_prosub.nome, est_pro001.pro001';
else
vsql = vsql || ' order by cmp_for001.nome, est_prosub.nome, est_pro001.pro001';
for
execute statement vsql
into :pro001, :nome, :est_prosub_nome, :cmp_for001_nome, :qtdade_estoque
do begin
for select coalesce(sum(vda_vda002.quantidade),0) as VENDIDO
from vda_vda002, vda_vda001
where vda_vda002.pro001 = :pro001
and vda_vda002.vda001 = vda_vda001.vda001
and vda_vda002.emp001 = vda_vda001.emp001
and vda_vda001.emissao >= :data_ini and vda_vda001.emissao <= :data_fin
and vda_vda001.emp001 = :emp001
into :qtdade_venda
do begin
for select coalesce(sum(est_promov.quantidade),0) as COMPRADO
from est_promov
where est_promov.pro001 = :pro001
and est_promov.data >= :data_ini and est_promov.data <= :data_fin
and est_promov.prohis = 2
and est_promov.emp001 = :emp001
into :qtdade_compra
do
suspend;
end
end
end
GOSTEI 0