Média de horas - Firebird
22/03/2023
0
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.
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
Post mais votado
24/03/2023
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
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.
select dateadd( minute, avg( datediff( minute, hora_chegada, date '1-Jan-2023' ) ), date '1-Jan-2023' ) from chegadas
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.
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:
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
24/03/2023
Dirceu Morais
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.
Clique aqui para fazer login e interagir na Comunidade :)