SQL/Contar campos

Firebird

29/12/2005

Olá amigos, observem o código abaixo:

function TFormFichaIndividual.TstNum(numero: double): Boolean;
begin
Result := False;
if numero <> 0 then
begin
valor := valor + numero;
Result := True;
end;
end;

procedure TFormFichaIndividual.MediaB1;
var
cont: integer;
begin
cont := 0;
valor := 0;
if TstNum(NotasN1B1.Value) then cont := cont + 1;
if TstNum(NotasN2B1.Value) then cont := cont + 1;
if TstNum(NotasN3B1.Value) then cont := cont + 1;
if TstNum(NotasN4B1.Value) then cont := cont + 1;
if cont > 0 then
NotasMEDIAB1.Value := ((valor / cont) * 10) / 10;
end;

procedure TFormFichaIndividual.MediaB2;
var
cont: integer;
begin
cont := 0;
valor := 0;
if TstNum(NotasN1B2.Value) then cont := cont + 1;
if TstNum(NotasN2B2.Value) then cont := cont + 1;
if TstNum(NotasN3B2.Value) then cont := cont + 1;
if TstNum(NotasN4B2.Value) then cont := cont + 1;
if cont > 0 then
NotasMEDIAB2.Value := ((valor / cont) * 10) / 10;
end;

procedure TFormFichaIndividual.NotasCalcFields(DataSet: TDataSet);
begin
MediaB1;
MediaB2;
NotasMEDIAGERAL.Value := (NotasMEDIAB1.Value + NotasMEDIAB2.Value) / 2;
NotasMEDIAFINAL.Value := ((6 * NotasMEDIAGERAL.Value) + (4 * NotasRECUPERACAO.Value)) / 10;
NotasFREQUENCIA.Value := (NotasFALTAB1.Value + NotasFALTAB2.Value) / Notas.FieldByName(´CH´).AsInteger * 100;
NotasFALTAS.Value := NotasFALTAB1.Value + NotasFALTAB2.Value;
end;

Eu gostaria de transforma todo esse calculo em SQL para usar no Firebird,
por exemplo:

Se eu tenho quatro campos com valor > do que 0 a divisão vai se 4, mais se dos 4 campos obrigatórios para o calculo tenho só 2 campos > 0 a divisão vai ser 2, e assim sucessivamente.

Alguém pode me ajudar?


Belo

Belo

Curtidas 0

Respostas

Lucianogar

Lucianogar

29/12/2005

Não sei se pode ajudar, mas você poderia criar um StoreProcedure para fazer os calculos e utilizar uma select simples que retorne apenas o resultado da média.

PROCEDURE:
CREATE PROCEDURE SP_MEDIA(
    VL_NUM1 NUMERIC(15,2),
    VL_NUM2 NUMERIC(15,2),
    VL_NUM3 NUMERIC(15,2),
    VL_NUM4 NUMERIC(15,2))
RETURNS (VL_MEDIA NUMERIC(15,2))
AS
declare variable NumValidos integer;
declare variable ValorTotal numeric(15,2);
begin
  NumValidos = 0;
  ValorTotal = 0;
  if ( (:VL_NUM1 IS NOT NULL) or (:VL_NUM1 = 0) ) then
  Begin
    NumValidos = :NumValidos + 1;
    ValorTotal = :ValorTotal + :VL_NUM1;
  End
  if ( (:VL_NUM2 IS NOT NULL) or (:VL_NUM2 = 0) ) then
  Begin
    NumValidos = :NumValidos + 1;
    ValorTotal = :ValorTotal + :VL_NUM2;
  End
  if ( (:VL_NUM3 IS NOT NULL) or (:VL_NUM3 = 0) ) then
  Begin
    NumValidos = :NumValidos + 1;
    ValorTotal = :ValorTotal + :VL_NUM3;
  End
  if ( (:VL_NUM4 IS NOT NULL) or (:VL_NUM4 = 0) ) then
  Begin
    NumValidos = :NumValidos + 1;
    ValorTotal = :ValorTotal + :VL_NUM4;
  End
  if (:NumValidos = 0) then
    Exit;

  VL_MEDIA = ((ValorTotal / NumValidos) * 10) / 10;
  suspend;
end


SELECT:
select VL_MEDIA from SP_MEDIA(20,30,10,null) ou
select VL_MEDIA from SP_MEDIA(20,30,null,null) ou
select VL_MEDIA from SP_MEDIA(20,30,10,5)



GOSTEI 0
Lucianogar

Lucianogar

29/12/2005

No lugar de (:VL_NUM1 = 0) vc colocar (:VL_NUM1 <> 0)


GOSTEI 0
Belo

Belo

29/12/2005

No lugar de (:VL_NUM1 = 0) vc colocar (:VL_NUM1 <> 0)


Valeu, Luciano.

Muito obrigado e um Feliz 2006!


GOSTEI 0
POSTAR