Como converter um intervalo em várias horas com o postgres?

161

Digamos que eu tenha um intervalo como

4 days 10:00:00

no postgres. Como converter isso para um número de horas (106 neste caso?) Existe uma função ou devo morder a bala e fazer algo como

extract(days, my_interval) * 24 + extract(hours, my_interval)
agnul
fonte
9
Nota: Se o seu intervalo contiver meses ou anos, não há resposta definida de quantas horas existem, pois o número de dias em um mês ou ano varia. Então, cuidado com isso!
Teddy

Respostas:

313

Provavelmente, a maneira mais fácil é:

SELECT EXTRACT(epoch FROM my_interval)/3600
Magnus Hagander
fonte
6
E talvez chão ou converter o resultado para inteiro se o intervalo contém minutos e / ou segundos
rasjani
64
Extrair época? Oh meu Deus, isso não teria passado pela minha cabeça em um milhão de anos.
Agnul 04/06/09
4
SELECT EXTRACT (época do meu_interval / 3600) (o intervalo possui suporte nativo 'dividir número inteiro', o resultado é intervalo e o resultado da extração é inteiro, não flutuante). Assim. Autocast / Piso realizado.
Offenso
19
Aviso: a extração simples da época implica implicitamente que um mês = 30 dias e um ano = 365,25 dias.
Teddy
@Teddy, o que podemos fazer com isso? Como evitar esse problema e obter um número real de épocas?
Asmox
18

Se você quiser um número inteiro, ou seja, número de dias:

SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int
Pujan Srivastava
fonte
Ótimo! Obrigado por isso :) No entanto, descobri que agora podemos modificá-lo SELECT extract('epoch' FROM age('2014-08-02'::timestamp)) / 86400(estou usando a página 9.4), pois age(ts)use automaticamente CURRENT_DATEquando apenas um argumento.
1111161171159459134
7
Aviso: a extração simples da época implica implicitamente que um mês = 30 dias e um ano = 365,25 dias.
Teddy
3

Para obter o número de dias, a maneira mais fácil seria:

SELECT EXTRACT(DAY FROM NOW() - '2014-08-02 08:10:56');

Tanto quanto eu sei, ele retornaria o mesmo que:

SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int;
belveryin
fonte
27
Se o seu intervalo for '1 month 0 days', usar extract(day from …)será 0o resultado.
Underyx
1
select floor((date_part('epoch', order_time - '2016-09-05 00:00:00') / 3600)), count(*)
from od_a_week
group by floor((date_part('epoch', order_time - '2016-09-05 00:00:00') / 3600));

A ::intconversão segue o princípio do arredondamento. Se você deseja um resultado diferente, como arredondamento para baixo, pode usar a função matemática correspondente, como floor.

haoming
fonte
1

Se você converter o campo da tabela:

  1. Defina o campo para que ele contenha segundos:

     CREATE TABLE IF NOT EXISTS test (
         ...
         field        INTERVAL SECOND(0)
     );
  2. Extraia o valor. Lembre-se de lançar para int de outra maneira, você pode obter uma surpresa desagradável quando os intervalos forem grandes:

    EXTRACT(EPOCH FROM field)::int

Janek Olszak
fonte
Não acho que o Redshift suporte o tipo de dados INTERVAL. Seria apenas BIGINT.
matt2000 26/03/19
-4
         select date 'now()' - date '1955-12-15';

Aqui está a consulta simples que calcula o total de dias.

Arunkumar Papena
fonte
4
Isso não leva um valor de intervalo.
Teddy