Fórum Média de horas - Firebird #619697
22/03/2023
0
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
Curtir tópico
+ 0Post mais votado
24/03/2023
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

Gostei + 1
Mais Posts
23/03/2023
Arthur Heinrich
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 |
Gostei + 0
24/03/2023
Dirceu Morais
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
Gostei + 0
24/03/2023
Dirceu Morais
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 |
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.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)