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)

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

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

Ó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;

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.


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


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.


4
Isso não leva um valor de intervalo.
Teddy
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.