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)
agnul
la source
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
Magnus Hagander
la source
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
Pujan Srivastava
la source
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;
belveryin
la source
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.

haoming
la source
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

Janek Olszak
la source
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.

Arunkumar Papena
la source
4
Cela ne prend pas une valeur d'intervalle.
Teddy du