Media de tempo considerando um intervalo de tempo usando POSTGRESQL

boa tarde pessoal, to tentando criar uma view onde é exibido varios dados de varias tabelas mas to com dificuldade em um campo especifico, onde tenho que exibir uma media de tempo exemplo: tenho a coluna inicio_espera e a coluna inicio_atendimento tipo timestamp, tenho que calcular o intervalo de tempo entre as 2 colunas e calcular a media de tempo de todas as linhas segue a baixo como ta minha query

select distinct on (lugar)
tend.cod_api as unidade,
tend.descricao as lugar,
(select count(tas1.id) from tb_atend_senhas tas1 where tas1.id_local = tend.id and date(tas1.dh_emissao) = date(now()) ) as emitidas,
(select count(tas2.id) from tb_atend_senhas tas2 where tas2.id_local = tend.id and date(tas2.dh_emissao) = date(now()) and tas2.dh_inicio_atendimento is null ) as espera
from tb_enderecos tend
join tb_empresa tbemp on tbemp.id = tend.id_empresa

tenho nem ideia de como consigo fazer isso

OBS: So calcular o tempo com a coluna inicio_ atendimento não seja null

Como tu mesmo dizes, tens de calcular o intervalo de tempo (aqui em segundos e assumindo que são no mesmo dia):

 DATE_PART('hour', dh_inicio_atendimento - dh_inicio_espera) * 3660 +
 DATE_PART('minute', dh_inicio_atendimento - dh_inicio_espera) * 60 +
 DATE_PART('second',dh_inicio_atendimento - dh_inicio_espera)

Fazendo a média é simples:

AVG(valor)

Converter este valor depois para um formato legivel de hora minuto segundo é assim

TO_CHAR((avg(valor) || ' second')::interval, 'HH24:MI:SS')

Juntando tudo isso:

SELECT 
    (...)
   TO_CHAR(
     avg(
       (SELECT DATE_PART('hour', tas3.dh_inicio_atendimento - tas3.dh_inicio_espera) * 3660 +
             DATE_PART('minute', tas3.dh_inicio_atendimento - tas3.dh_inicio_espera) * 60 +
             DATE_PART('second',tas3.dh_inicio_atendimento - tas3.dh_inicio_espera) 
      from tb_atend_senhas tas3.
     where tas3.id_local = tend.id 
       and date(tas3.dh_emissao) = date(now()) 
       and tas3.dh_inicio_atendimento is not null )) || ' second')::interval, 'HH24:MI:SS')   as media
(...)

to entendendo a logica, porem não conheço muito bem esses comandos e levantou erro em alguns pontos

  1. SQL Error [42601]: ERROR: syntax error at or near “.” Position: 712
    aqui eu removi o ponto do tas3 dps do from ai surgiu essa
  2. SQL Error [42601]: ERROR: syntax error at or near “)” Position: 898
    aqui eu removi o parênteses dps do ’ second’ ai surgiu esse outro erro
  3. SQL Error [22007]: ERROR: invalid input syntax for type interval: " second" Position: 864
    aqui eu substitui o || ’ second’)::interval, ‘HH24:MI:SS’ por , ‘HH24:MI:SS’ e surgiu esse erro
  4. SQL Error [42803]: ERROR: column “tend.cod_api” must appear in the GROUP BY clause or be used in an aggregate function Position: 32

ai eu ja não sei mais oq fazer kkk poderia me ajudar ?

Certo, foi copy paste para todos os alias, ficou o ponto a mais.

Aqui não deverias ter removido esse. Deve é faltar um antes de avg( passando a ser (avg(

Este é por causa do anterior. Deve desaparecer com aquele parenteses

Hmmm… Melhor passar o avg para dentro do select então, vamos a ver se não troco os ()

SELECT 
 (...)
TO_CHAR(
 (
   (SELECT avg(DATE_PART('hour', tas3.dh_inicio_atendimento - tas3.dh_inicio_espera) * 3660 +
         DATE_PART('minute', tas3.dh_inicio_atendimento - tas3.dh_inicio_espera) * 60 +
         DATE_PART('second',tas3.dh_inicio_atendimento - tas3.dh_inicio_espera)) 
  from tb_atend_senhas tas3
 where tas3.id_local = tend.id 
   and date(tas3.dh_emissao) = date(now()) 
   and tas3.dh_inicio_atendimento is not null ) || ' second')::interval, 'HH24:MI:SS')   as media

(…)

meu amigo funcionou, obrigado :smiley:

1 curtida