Média de horas - Firebird
Olá colegas estou precisando de pegar a média de hora em uma tabela firebird.
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.
Com esta função acima eu consigo transformar em minutos. Não sei se é o caminho.
Espero ajuda dos colegas.
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 chegadasCom esta função acima eu consigo transformar em minutos. Não sei se é o caminho.
Espero ajuda dos colegas.
Dirceu Morais
Curtidas 0
Melhor post
Emerson Nascimento
24/03/2023
uma query simples não resolve o problema?
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
GOSTEI 1
Mais Respostas
Arthur Heinrich
22/03/2023
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.
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
GOSTEI 0
Dirceu Morais
22/03/2023
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.
Mas eu consegui resolver da seguinte maneira:
PODE MARCAR COMO RESOLVIDO
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
GOSTEI 0
Dirceu Morais
22/03/2023
uma query simples não resolve o problema?
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