Fórum Média de horas - Firebird #619697

22/03/2023

0

Olá colegas estou precisando de pegar a média de hora em uma tabela firebird.
1
2
3
4
5
6
7
8
9
14:57
15:07
15:04
14:50
15:09
15:01
15:00
---------
Média: 15:01


Usando o AVG para fazer a média dá erro:
Dynamic SQL Error.
expression evaluation not supported.
Argument for AVG in dialect 3 must be numeric.

Engraçado que na função do IBexpert se eu pedir a AVG ele me mostra: AVG = 30/12/1899 15:01:30.

1
2
3
4
5
6
7
8
select
         AVG(
              (CAST(SUBSTRING(hora_chegada FROM 1 FOR 2) AS INTEGER) * 60)  +
              (CAST(SUBSTRING(hora_chegada FROM 4 FOR 2) AS INTEGER))
              )
           HorasEmMinutos
 
FROM   chegadas

Com esta função acima eu consigo transformar em minutos. Não sei se é o caminho.

Espero ajuda dos colegas.
Dirceu Morais

Dirceu Morais

Responder

Post mais votado

24/03/2023

uma query simples não resolve o problema?
1
2
3
4
5
6
7
8
9
10
11
12
select
   replace(
      cast(
         avg(
            (CAST(SUBSTRING(hora_chegada FROM 1 FOR 2) AS INTEGER) * 60.0)  +
            CAST(SUBSTRING(hora_chegada FROM 4 FOR 2) AS INTEGER)
         )/60.0
         as varchar(5)
      ), '.',':'
   ) media
from
   chegadas

Emerson Nascimento

Emerson Nascimento
Responder

Gostei + 1

Mais Posts

23/03/2023

Arthur Heinrich

O problema de transformar em minutos, como você fez, é que depois de calcular a média você precisa transformar em horas:minutos.

Talvez uma maneira mais fácil seja transformar a data em uma quantidade de minutos a partir de uma data fixa (data - data_fixa). Você então calcula a média de minutos e volta a somar à data fixa.

1
2
select dateadd( minute, avg( datediff( minute, hora_chegada, date '1-Jan-2023' ) ), date '1-Jan-2023' )
from chegadas
Responder

Gostei + 0

24/03/2023

Dirceu Morais

Obrigado amigo pela dica,

select dateadd( minute, avg( datediff( minute, hora_chegada, date '1-Jan-2023' ) ), date '1-Jan-2023' )
from chegadas


Mas deu erro na execução do comando.
1
2
expression evaluation not supported.
The result of DATE-TIME or TIME-DATE in DATEDIFF cannot be expressed in HOUR, MINUTE, SECOND and MILLISECOND.



Mas eu consegui resolver da seguinte maneira:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
select Cast( AVG(
          (CAST(SUBSTRING(hora_chegada FROM 1 FOR 2) AS INTEGER) * 60)  +
          '(CAST(SUBSTRING(hora_chegada FROM 4 FOR 2) AS INTEGER))
          ) as float) / 60 as Retorno
     From chegadas
  //Procuro a posição do ponto decimal  
  p := Pos(',',retorno);
 //Se não tem o ponto decimal, se não tem pq é hora cheia, exemplo: 8
  if P = 0  then
  Begin
     Hr := retorno; //Hora vai ser o resultado
     mn := 0;      //Zero minutos
  End
  else
  begin
     //encontra o total de horas do numero inteiro. Ex. se o resultado for 7,066 vai buscar 7 horas
     Hr := Copy(retorno,1,p-1);
     //Acrescenta 0 no lugar das horas e busca os decimais. Ex. Se era 7,066  os minutos vão ficar 0,066
     Parada := '0'+Copy(retorno,p,8);
     //Transforma a string em Float
     mn  := StrToFloatDef(Parada,0);
     //multiplico os decimais por 60 minutos e arredondo o valor. Ex. 0,066 * 60 = 3,96
     mn  := RoundTo(mn * 60,-2);
  end;
 //Transformo o resultado de hr=hora e mn=minutos em  hh:mm.
 //Acrescentando zeros ao numero inteiro.  Ex. hr=7 mn 4  em 07:04
  hm := AcrescZero(hr,2) +':'+Copy(AcrescZero(FloatToStr(mn),2),1,2);



PODE MARCAR COMO RESOLVIDO
Responder

Gostei + 0

24/03/2023

Dirceu Morais

uma query simples não resolve o problema?
1
2
3
4
5
6
7
8
9
10
11
12
select
   replace(
      cast(
         avg(
            (CAST(SUBSTRING(hora_chegada FROM 1 FOR 2) AS INTEGER) * 60.0)  +
            CAST(SUBSTRING(hora_chegada FROM 4 FOR 2) AS INTEGER)
         )/60.0
         as varchar(5)
      ), '.',':'
   ) media
from
   chegadas

Ler Mais...



Obrigado amigo, bateu na trave.

Com essa sua dica, no exemplo mencionado, o resultado dá 8:98, neste caso, teria que separar as 8h pegar os 98 minutos, e multiplicar por 60 (pq dividimos tudo por 60). Pegaria o resultado obtido, no caso 98x60=5880min, arredondando 59min, e ai trocaria os 98 por 59, ficando assim 8:59.
Em outro exemplo, que o resultado seria 10:34, teria que multiplicar 34x60=2040, trocando e arredondando, teriamos 10:20.
Responder

Gostei + 0

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

Aceitar