Select com Sum() e Having()

Firebird

03/10/2005

caros, boa tarde.

tenho uma tabela de produtos,
e to fazendo uma curva ABC por freq. de vendas.
ja montei e realizei os calculos.

estrutura
codproduto integer;
TotalFrequencia numeric(13,4),
IndiceReferenteTotalFrequencia (numeric(13,4),

os calculos acimas, ja estao prontos e gravados na tabela.

Agora,
Tem como fazer um select que:
Selecione os primeiros registros em que:
a soma de (IndiceReferenteTotalFrequencia) seja até 20¬ ?


em sql: +- assim;

SELECT
CODIGOPRODUTO FROM <TABELA>
HAVING
SUM(INDICEREFERENTETOTALFREQUENCIA) FIQUE ENTRE 20¬.
ORDER BY IndiceReferenteTotalFrequencia DESC



Obrigado.


Pedih

Pedih

Curtidas 0

Respostas

Bruno Belchior

Bruno Belchior

03/10/2005

Select CodigoProduto, Sum(IndiceReferenteTotalFrequencia) from Tabela 
group by CodigoProduto
having
Order By IndiceReferenteTotalFrequencia desc
Sum(IndiceReferenteTotalFrequencia) <= 20



GOSTEI 0
Bruno Belchior

Bruno Belchior

03/10/2005

desculpe
select CodigoProduto, Sum(IndiceReferenteTotalFrequencia) from Tabela 
group by CodigoProduto 
order by IndiceReferenteTotalFrequencia desc 
having Sum(IndiceReferenteTotalFrequencia) <= 20



GOSTEI 0
Pedih

Pedih

03/10/2005

Bruno, boa tarde.

select CodigoProduto, Sum(IndiceReferenteTotalFrequencia) from tabela group by CodigoProduto
order by IndiceReferenteTotalFrequencia desc
having Sum(IndiceReferenteTotalFrequencia) <= 20


nao funcionou

dá erro na linha do HAVING.
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 7, char 1.
having.


Obrigado pela atencao.


GOSTEI 0
Afarias

Afarias

03/10/2005

ORDER BY é sempre a última cláusula de um SQL, sendo assim apenas coloque o HAVING antes do ORDER BY (e depois do GROUP BY, claro!)


T+


GOSTEI 0
Pedih

Pedih

03/10/2005

Afarias, boa tarde.

vou expor meu problema:

é o seguinte:

Tenho uma tabela, com 20.000 itens (produtos),
Campos.
CodProduto Integer,
FreqVenda Numeric(13,4)
FreqIndice Numeric(13,4).

montei um select que:
alimenta, a quantidade vendida de cada item, acumulando no campo
FreqVenda.
Ja o campo FreqIndice, é alimentado de acordo com a FreqVenda de cada item / Soma(FreqVenda).
até aqui, tá certo.

bom:
vou fazer uma classificacao ABC:
A 20¬
B 50¬
C 30¬
total (100¬).

preciso listar todos os itens que atingem a Classificacao ´A´, ou seja 20¬.

select CodProduto, FreqIndice from <tabela>
na condicao de: <somando 1 a 1 até dár 20¬>.

Entendeu ?

Obrigado pela gentil atencao, by.


GOSTEI 0
Afarias

Afarias

03/10/2005

|Entendeu ?

não! :(


|na condicao de: <somando 1 a 1 até dár 20¬>.

:? isso ai não me ficou claro!

se puder explicar melhor...

T+


GOSTEI 0
Pedih

Pedih

03/10/2005

Afarias,
é o seguinte:


preciso dar um select que:

me retorne, registros cuja soma de um campo nao ultrapasse um indice qualquer.
exemplo: QUERO INDICE DE 20.

item indice
A 1,05
B 4,05 --SOMA: 5,10
C 9,50 --SOMA: 14,60
D 1,00 --SOMA: 15,60
E 2,33 --SOMA: 17,93
F 2,00 --SOMA: 19,93 -- HORA QUE CHEGAR AQUI, DEVE PÁRAR.
G 5,00 --SOMA: 24,93
H 1,00 --SOMA: 25,93


entendeu ?

é o um select, que deve realizar uma soma, e quando esta soma chegar num determinado valor informado, deve parar de selecionar os registros.


Obrigado.


GOSTEI 0
Bruno Belchior

Bruno Belchior

03/10/2005

você já armazena o campo como gostaria q somasse ou deve fazer uma conversão antes? caso não, aquele código postado acima (com a correção do colega AFarias) faz exatamente isso...


GOSTEI 0
Afarias

Afarias

03/10/2005

|entendeu ?

ah, agora sim...!!!

vc não presisa de um SELECT ... precisa de um STORED PROC

só um procedimento pra fazer o q vc deseja.


T+


GOSTEI 0
Pedih

Pedih

03/10/2005

Afarias,
por store_proc, nao consegui enxergar a solucao.


:idea: :idea:

Campos:

CodProduto Integer,
Indice Numeric(13,4);

como vc montaria uma store_proc ??

sao 20.000 itens, e a soma do campo Indice, deve parar qdo atingir 20¬.Lebrando que a soma total deste campo = 100¬.

obrigado.


GOSTEI 0
Afarias

Afarias

03/10/2005

algo tipo:

set term ^;

create procedure produtos_indice (fator numeric(13,4))
returns (codProduto integer, indice numeric(13,4)) 
as
  declare variable total numeric(13,4);
begin
  total = 0;
  for select codProduto, indice from tabela
       order by <alguma coisa>
       into :codProduto, :indice do
  begin
    total = total + indice;
    if (total <= fator) do
      suspend;
    else
      exit;
  end
end^


e vc usa na forma:

select * from produtos_indice(20)


T+


GOSTEI 0
Pedih

Pedih

03/10/2005

Afarias:
funcionou perfeito. Parabens.


um outro detalhe.

select * from produtos_indice(20)



vamos supor que:
eu queira fazer ja um update, (curva ABC).

os primeiros 20¬ do fator, serao = ´A´,
de 20,01 até 50¬, serao ´B´,
de 51,01 até 100, serao ´C´,

como eu faco um update ja verificando os indices ??
o campo do update é Curva(Char(1)).

Obrigado pela atencao


GOSTEI 0
Pedih

Pedih

03/10/2005

Afarias,

ja encontrei a solucao:
Obrigado mesmo assim, valeu:

ficou assim:

REATE PROCEDURE PRODUTOS_INDICE(
FATORA NUMERIC(13,4),
FATORB NUMERIC(13,4),
FATORC NUMERIC(13,4))
RETURNS (
CODPRODUTO INTEGER,
INDICE NUMERIC(13,4))
AS
declare variable total numeric(13,4);
declare variable Letracurva Char(1);
declare variable SaldoEstoque numeric(13,4);
begin
total = 0;
for select j.Codproduto,
j.Curvaindice from <tabela> j
order by j.Curvaindice Desc
into :codProduto, :indice do
begin
total = total + indice;

If (Total <= Fatora) Then /* CURVA A */
Letracurva = ´A´;

If (Total > Fatora And Total <= (Fatora + Fatorb)) then /* CURVA b */
Letracurva = ´B´;

If (Total > (Fatora + Fatorb)) Then
Letracurva = ´C´;

If (:Indice = 0) Then
Begin
Letracurva = ´E´;
Select e.Quantestoque From Estoqueproduto e
where
e.Codproduto = :Codproduto
And e.Empresa = 1
Into :Saldoestoque;

If (:Saldoestoque Is Null) Then
Saldoestoque = 0;

if (:Saldoestoque > 0) then
Letracurva = ´D´;
end

Update <tabela> j2 Set
j2.Curvacatalogo = :Letracurva
Where j2.Codproduto = :Codproduto;

-- suspend;
-- end
-- else
-- exit;
end
end


GOSTEI 0
POSTAR