Comment convertir un intervalle en nombre d'heures avec postgres?


161

Dis que j'ai un intervalle comme

4 days 10:00:00

dans postgres. Comment puis-je convertir cela en un nombre d'heures (106 dans ce cas?) Y a-t-il une fonction ou devrais-je mordre la balle et faire quelque chose comme

extract(days, my_interval) * 24 + extract(hours, my_interval)

9
Remarque: Si votre intervalle contient des mois ou des années, il n'y a pas de réponse définie sur le nombre d'heures, car le nombre de jours dans un mois ou une année varie. Alors attention à ça!
Teddy

Réponses:


314

Le moyen le plus simple est probablement:

SELECT EXTRACT(epoch FROM my_interval)/3600

6
Et peut-être plancher ou convertir le résultat en entier si l'intervalle contient des minutes et / ou des secondes
rasjani

64
Extraire l'époque? Oh mon Dieu, cela ne m'aurait pas traversé l'esprit dans un million d'années.
agnul le

5
SELECT EXTRACT (epoch FROM my_interval / 3600) (l'intervalle a le support natif de 'divide integer', le résultat est l'intervalle et le résultat de l'extraction est un entier, pas un flottant). Alors. Autocast / étage terminé.
Offenso

19
Attention: l'extraction simple de l'époque suppose implicitement qu'un mois = 30 jours et un an = 365,25 jours.
Teddy

@Teddy, que pouvons-nous en faire? Comment éviter ce problème et obtenir un nombre réel d'époques?
Asmox

18

Si vous voulez un nombre entier, c'est-à-dire le nombre de jours:

SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int

Génial! Merci pour cela :) Pourtant, j'ai trouvé que nous pouvons maintenant modifier cela pour être SELECT extract('epoch' FROM age('2014-08-02'::timestamp)) / 86400(j'utilise Pg 9.4), car age(ts)utiliser automatiquement CURRENT_DATEquand un seul argument.
1111161171159459134

7
Attention: l'extraction simple de l'époque suppose implicitement qu'un mois = 30 jours et un an = 365,25 jours.
Teddy

3

Pour obtenir le nombre de jours, le moyen le plus simple serait:

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

Autant que je sache, il renverrait le même que:

SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int;

28
Si votre intervalle est '1 month 0 days', utiliser extract(day from …)vous donnera 0comme résultat.
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));

La ::intconversion suit le principe de l'arrondi. Si vous voulez un résultat différent, comme un arrondi vers le bas, vous pouvez utiliser la fonction mathématique correspondante telle que floor.


1

Si vous convertissez un champ de table:

  1. Définissez le champ pour qu'il contienne des secondes:

     CREATE TABLE IF NOT EXISTS test (
         ...
         field        INTERVAL SECOND(0)
     );
    
  2. Extrayez la valeur. N'oubliez pas de lancer int autrement vous pouvez avoir une mauvaise surprise une fois que les intervalles sont grands:

    EXTRACT(EPOCH FROM field)::int


Je ne pense pas que Redshift prend en charge le type de données INTERVAL. Ce serait juste BIGINT.
matt2000

-4
         select date 'now()' - date '1955-12-15';

Voici la requête simple qui calcule le nombre total de jours.


4
Cela ne prend pas une valeur d'intervalle.
Teddy du
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.