Fórum Ajuda num Select com Sum #369774

15/04/2009

0

Bom amigos,
segue abaixo o select pretendo apresentar:

- Código do Produto
- Nome do Produto
- Soma das Entradas do período
- Soma das Vendas do período

No banco tenho:
- 1 entrada apenas com 5 unidades
- 16 vendas de uma unidade cada

Com esse select me é retornado 80 entradas que pelo que pude descobrir, ele está somando as 5 unidades a cada ocorrência da venda.

O resultado: 80 entradas e 16 saídas

Se filtrar para pegar apenas uma saída, aí me retorna as 5 reais entradas, se filtrar para 2 saídas me retorna 10 entradas, e assimsucessivamente.


select produtos.codpro,
       produtos.nompro,
       sum(entradasi.qtd) as qtde,
       sum(vendasi.qtd) as qtds

from produtos

left join vendasi   on vendasi.codpro  =produtos.codpro
left join vendas    on vendas.pedido   =vendasi.pedido

left join entradasi on entradasi.codpro=produtos.codpro
left join entradas  on entradas.codfor =entradasi.codfor and entradas.nota=entradasi.nota

where produtos.codpro  = 3 and
      vendas.datven    between :dat1 and :dat2 and
      entradas.entrada between :dat1 and :dat2

group by produtos.codpro,produtos.nompro


Aguardo uma ajuda


Aldus

Aldus

Responder

Posts

15/04/2009

Lehapan

Caro aldus,

não cheguei a testar o SQL, mas acho que é isto.

SELECT
  prod.CodPro,
  prod.NomPro,
  ( SELECT
      SUM(enti.Qtd)
    FROM
      ENTRADASI enti ON ( enti.CodPro = prod.CodPro )
        INNER JOIN ENTRADAS ent ON ( ent.CodFor = enti.CodFor AND ent.Nota = enti.Nota )
    WHERE
      ent.Entrada BETWEEN :dat1 AND :dat2
  ) AS QtdeEnt,
  ( SELECT
      SUM(enti.Qtd)
    FROM
      VENDASI veni ON ( veni.CodPro = prod.CodPro )
        INNER JOIN VENDAS ven ON ( ven.Pedido = veni.Pedido )
    WHERE
      ven.DataVen BETWEEN :dat1 AND :dat2
  ) AS QtdeSai
FROM
  PRODUTOS prod
WHERE
  prod.CodPro = 3
GROUP BY
  prod.CodPro,
  prod.NomPro


espero ter ajudado.


Responder

Gostei + 0

15/04/2009

Aldus

Olá Paulista,

ocorre erro nas duas linhas abaixo em ´ON´

      ENTRADASI enti ON ( enti.CodPro = prod.CodPro )
      VENDASI veni ON ( veni.CodPro = prod.CodPro )


att


Responder

Gostei + 0

15/04/2009

Lehapan

Ok, você esta certo...como não executei o SQL, não percebi que tinha me passado em um erro deste...me desculpe...mas agora segue o SQL sem erro.

SELECT
  prod.CodPro,
  prod.NomPro,
  ( SELECT
      SUM(enti.Qtd)
    FROM
      ENTRADASI enti
        INNER JOIN ENTRADAS ent ON ( ent.CodFor = enti.CodFor AND ent.Nota = enti.Nota )
    WHERE
      enti.CodPro = prod.CodPro AND
      ent.Entrada BETWEEN :dat1 AND :dat2
  ) AS QtdeEnt,
  ( SELECT
      SUM(enti.Qtd)
    FROM
      VENDASI veni
        INNER JOIN VENDAS ven ON ( ven.Pedido = veni.Pedido )
    WHERE
      veni.CodPro = prod.CodPro AND
      ven.DataVen BETWEEN :dat1 AND :dat2
  ) AS QtdeSai
FROM
  PRODUTOS prod
WHERE
  prod.CodPro = 3
GROUP BY
  prod.CodPro,
  prod.NomPro



Responder

Gostei + 0

15/04/2009

Aldus

Olá,
Eliminou-se os erros, só que não retornou as quantidades.

Coloquei o script das tabelas e o script de select em
http://www.aldus.com.br/tabela.sql


Responder

Gostei + 0

16/04/2009

Aldus

up


Responder

Gostei + 0

16/04/2009

Lehapan

Caro Aldo,

Se você possui:
- 1 entrada apenas com 5 unidades
- 16 vendas de uma unidade cada

assim como você disse, o resultado que quer é:

CodPro, NomePro, QtdE, QtdS
X, NomeX, 5, 16

seria isto, a soma das quantidades vendidas ou compradas?


Responder

Gostei + 0

16/04/2009

Aldus

Sim, é isso que quero.


Responder

Gostei + 0

16/04/2009

Lehapan

olha, testei com um banco de dados que tenho sobre vendas e compras, e funcionou perfeitamente, verifique se os campos dos JOIN´s estão corretos e qualquer coisa tente efetuar somente a soma das entradas, sem as saídas, para ver se este o caso também.

ah, outra coisa, utilizo o Firebird 2.
qualquer coisa é só perguntar.

SELECT
  prod.CodPro,
  prod.NomPro,
  ( SELECT
      SUM(enti.Qtd)
    FROM
      ENTRADASI enti
        INNER JOIN ENTRADAS ent ON ( ent.CodFor = enti.CodFor AND ent.Nota = enti.Nota )
    WHERE
      enti.CodPro = prod.CodPro AND
      ent.Entrada BETWEEN :dat1 AND :dat2
  ) AS QtdeEnt,
  ( SELECT
      SUM(veni.Qtd)
    FROM
      VENDASI veni
        INNER JOIN VENDAS ven ON ( ven.Pedido = veni.Pedido )
    WHERE
      veni.CodPro = prod.CodPro AND
      ven.DataVen BETWEEN :dat1 AND :dat2
  ) AS QtdeSai
FROM
  PRODUTOS prod
WHERE
  prod.CodPro = 3
GROUP BY
  prod.CodPro,
  prod.NomPro



Responder

Gostei + 0

16/04/2009

Aldus

Olá Paulista, tbm uso fire 2.

Baixe o script que coloquei no link, crie as tabelas por ele e use o script que tem no inicio, coloque periodo de 01/01/2000 ate hoje que pegaria tudo e veja o resultado.

http://www.aldus.com.br/tabela.sql


Responder

Gostei + 0

16/04/2009

Aldus

coloquei o arquivo teste.fdb já com as tabelas e registros, nao coloquei a tabela de vendas, apenas a de entrada.

www.aldus.com.br/teste.zip


Responder

Gostei + 0

16/04/2009

Lehapan

Aldo, executei o SQL abaixo no banco que enviastes, e trouxe o seguinte resultado:

SQL:
SELECT
  prod.CodPro,
  prod.NomPro,
  ( SELECT
      SUM(enti.Qtd)
    FROM
      ENTRADASI enti
        INNER JOIN ENTRADAS ent ON ( ent.CodFor = enti.CodFor AND ent.Nota = enti.Nota )
    WHERE
      enti.CodPro = prod.CodPro AND
      ent.Entrada BETWEEN :dat1 AND :dat2
  ) AS QtdeEnt
FROM
  PRODUTOS prod
WHERE
  prod.CodPro = 3
GROUP BY
  prod.CodPro,
  prod.NomPro


Resultado:
CODPRO    NOMPRO   QTDEENT                               
     3          DIAROL          5


coloquei como parâmetro:
dat1 = 01/01/2000
dat2 = 16/04/2009

pelo que vi, esta trazendo o resultado corretamente, isto se você quer saber a o somatório das quantidades de entradas de um produto em um determinado período.

[b:059b1f26f1]Exemplo:[/b:059b1f26f1]
Entrada 1 - Data 01/03/2009 - Produto ´3´ - Qdte 30
Entrada 2 - Data 05/03/2009 - Produto ´3´ - Qdte 60
Entrada 3 - Data 05/03/2009 - Produto ´3´ - Qdte 7


O Resultado seria Produto ´3´ com Qtde 97...o SQL acima esta fazendo isto.

incluí dados na suas tabelas e ele me retornou os dados corretamente.

qualquer coisa pergunte.
espero ter ajudado.


Responder

Gostei + 0

16/04/2009

Aldus

Agora consegui tambem.

Acredite, estou usando o IBexpert para testar o select e quando ele abria a tela de parametros das datas, eu alterava apenas a primeira e deixava a outra como estava.
Aí, como está selecionada aquela caixa ao lado da lado, ele assumia, adivinhe, ´nulo´. Por isso não trazia nada.

Mas obrigado por montar o select, para as somas corretas.

ate+


Responder

Gostei + 0

16/04/2009

Aldus

Olá,
Tenho mais uma dúvida.

De posse dos campos entradas e saidas e tendo no cadastro de produtos o campo estoque, consigo montar assim:

CodPro, NomePro, EstoqueInicial, QtdE, QtdS, EstoqueFinal
X, NomeX, 31, 5, 16 , 20

Sendo que eu sei o estoque final + as saidas - as entradas = estoque inicial.

Select:

select codpro,
nomepro,
estoquefinal+saidas-entradas,
saidas,
entradas,
estoquefinal

É possível fazer esse tipo de matemática ?


Responder

Gostei + 0

16/04/2009

Lehapan

Bom, até pode ser feito em apenas um SQL, mas não aconselho, pois você teria que colocar os subselects novamente para isto, ou seja, você estaria fazendo um subselect para trazar a qtde de saídas, e outro subselect igual para calcular o estoque, e o mesmo para a qtde de entradas, isto ocupa muito processo do banco de dados.

Olha, o que você pode fazer é criar um campo virtual e depois manipular o resultado.
Exemplo:
SELECT
  prod.QtdeEntrada,
  prod.QtdeSaida,
  CAST( 0 AS NUMERIC(9,3) ) AS Saldo /* campo virtual*/
FROM
  PRODUTO prod


depois disto, você percorre todos os seus registros, no ClientDataSet ou na Query, e edita o registro atualizando o campo virtual.
Exemplo:
  with cdsMeuClient do
  begin
    First;
    while not Eof do
    begin
      Edit;
      fieldbyname(´Saldo´).AsFloat :=  fieldbyname(´QtdeSaida´).AsFloat - fieldbyname(´QtdeEntrada´).AsFloat;
      Post;

      Next;
    end;
  end;


Percorrer um resultado de um SQL e manipular os dados, as vezes é muito mais rápido, tem que levar em consideração o volume de registros que terá o banco.

Espero ter lhe ajudado.[/code]


Responder

Gostei + 0

16/04/2009

Aldus

Ola,

Era isso que estava precisando.

Obrigado pela ajuda.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar