web-dev-qa-db-fra.com

Comment convertir un intervalle du type "1 jour 01:30:00" en "25:30:00"?

Je dois ajouter des intervalles et utiliser le résultat dans Excel.

Puisque

sum(time.endtime-time.starttime)

renvoie l'intervalle sous la forme "1 jour 01:30:00" et ce format casse ma feuille de calcul Excel. Je pensais que ce serait bien d'avoir la sortie du type "25:30:00" mais je n'ai trouvé aucun moyen de le faire dans PostgreSQL. Documentation.

Quelqu'un peut-il m'aider ici?

20
Ole

Puisqu'il n'y a pas de solution exacte pour le sujet:

=> SELECT date_part('Epoch', INTERVAL '1 day 01:30:00') * INTERVAL '1 second' hours;
  hours
-----------
 25:30:00
(1 row)

Source: Documentation

18
zaratustra

La seule chose que je peux faire (à part analyser le nombre de jours et ajouter 24 heures à chaque fois) est:

mat=> select date_part('Epoch', '01 day 1:30:00'::interval);
 date_part 
-----------
     91800
(1 row)

Cela vous donnera le nombre de secondes, ce qui peut convenir pour Excel.

21
mat

Vous pouvez utiliser EXTRACT pour convertir l'intervalle en secondes.

SELECT EXTRACT(Epoch FROM INTERVAL '5 days 3 hours');
Result: 442800

Ensuite, vous devrez faire vos propres calculs (ou laisser Excel le faire).

Notez que '1 jour' n'équivaut pas nécessairement à '24 heures' - PostgreSQL ™ gère des choses comme un intervalle qui s'étend sur une transition DST.

18
slim

Si vous souhaitez que postgres gère le formatage HH: MM: SS à votre place, calculez la différence en secondes d'Epoch et convertissez-la en un intervalle échelonné en secondes:

SELECT SUM(EXTRACT(Epoch FROM time.endtime) - EXTRACT(Epoch FROM time.starttime))
         * INTERVAL '1 SECOND' AS hhmmss
12
pilcrow

Cela peut être fait, mais je crois que le seul moyen consiste à utiliser la monstruosité suivante (en supposant que le nom de colonne de votre intervalle de temps est "ti"):

select
              to_char(floor(extract(Epoch from ti)/3600),'FM00')
    || ':' || to_char(floor(cast(extract(Epoch from ti) as integer) % 3600 / 60), 'FM00')
    || ':' || to_char(cast(extract(Epoch from ti) as integer) % 60,'FM00')
    as hourstamp
from whatever;

Voir? Je t'ai dit que c'était horrible :)

Il aurait été agréable de penser que

select to_char(ti,'HH24:MI:SS') as hourstamp from t

cela aurait fonctionné, mais hélas, le format HH24 ne "absorbe" pas le débordement au-delà de 24. Ce qui précède vient (reconstruit à partir de la mémoire) de certains codes que j'ai écrits une fois. Pour éviter d'offenser ceux de constitution délicate, j'ai résumé les manigances ci-dessus dans une vue ...

0
dland

En SQL standard, vous voulez représenter le type sous la forme INTERVAL HOUR TO SECOND, mais vous avez une valeur de type INTERVAL DAY TO SECOND. Ne pouvez-vous pas utiliser un CAST pour obtenir le résultat souhaité? Dans Informix, la notation serait l'une des suivantes:

SUM(time.endtime - time.starttime)::INTERVAL HOUR(3) TO SECOND

CAST(SUM(time.endtime - time.starttime) AS INTERVAL HOUR(3) TO SECOND)

Le premier est, pour autant que je sache, une notation spécifique à Informix (ou, du moins, non standard); ce dernier est, je crois, la notation standard SQL.

0
Jonathan Leffler