web-dev-qa-db-fra.com

trouver le temps écoulé entre deux dates dans Oracle sql

j'ai besoin de trouver la différence entre l'heure au format hh: mm: ss

select msglog.id,max(msglog.timestamp) enddate,
   min(msglog.timestamp) startdate,
   enddate - startdate
   from MESSAGELOG msglog
   group by id

Dans la requête ci-dessus, msglog.timestamp est de type DATE.

Comment puis-je obtenir le temps écoulé ou la différence entre l'heure au format correct dans Oracle?

9
suni

Lorsque vous soustrayez deux valeurs DATE comme enddate - startdate vous obtenez la différence en jours avec une précision décimale, par exemple 1,5 signifierait 1 1/2 jours ou 36 heures. Vous pouvez le convertir en HH:MI:SS en utilisant beaucoup de mathématiques, mais un moyen plus simple consiste à convertir la valeur décimale en INTERVAL DAY TO SECOND valeur en utilisant la fonction NUMTODSINTERVAL :

  NUMTODSINTERVAL(enddate - startdate, 'DAY')

On pourrait penser que le TO_CHAR la fonction pourrait formater ceci comme HH:MI:SS, mais cela ne semble pas fonctionner de cette façon. Vous pouvez utiliser EXTRACT à la place et TO_CHAR pour vous assurer d'obtenir des zéros non significatifs:

 TO_CHAR(EXTRACT(HOUR FROM NUMTODSINTERVAL(enddate-startdate, 'DAY')), 'FM00')
   || ':' ||
 TO_CHAR(EXTRACT(MINUTE FROM NUMTODSINTERVAL(enddate-startdate, 'DAY')), 'FM00')
   || ':' ||
 TO_CHAR(EXTRACT(SECOND FROM NUMTODSINTERVAL(enddate-startdate, 'DAY')), 'FM00')

Le 00 une partie du code de format spécifie deux chiffres, avec un zéro en tête si nécessaire. La partie FM supprime l'espace de tête du résultat formaté, qui est réservé à un signe négatif si nécessaire.

Notez également que votre requête obtient des valeurs agrégées et les utilise dans la même liste SELECT. Oracle ne vous laissera pas faire cela. Essayez plutôt quelque chose comme ceci:

WITH StartEndByID AS (
  SELECT
    msglog.id,
    NUMTODSINTERVAL(max(msglog.timestamp) - min(msglog.timestamp), 'DAY') elapsed
  FROM messagelog msglog
  GROUP BY id
)
SELECT
  id,
  TO_CHAR(EXTRACT(HOUR FROM elapsed), 'FM00') || ':' ||
    TO_CHAR(EXTRACT(MINUTE FROM elapsed), 'FM00') || ':' ||
    TO_CHAR(EXTRACT(SECOND FROM elapsed), 'FM00') AS ElapsedHHMISS
FROM StartEndByID
20
Ed Gibbs

L'arithmétique des dates dans Oracle donne un nombre exprimé en jours. Donc, pour convertir en heures, vous multiplieriez par 24 puis trunc pour obtenir un nombre entier:

trunc(24 * (enddate - startdate))

Pour obtenir les minutes, convertissez la valeur des jours en minutes et mod() avec 60:

mod(trunc(24 * 60 * (enddate - startdate)), 60)

Pour les secondes, convertissez à nouveau les jours en secondes et mod() avec 60:

mod(trunc(24 * 60 * 60 * (enddate - startdate)), 60)

Vous pouvez maintenant les assembler pour obtenir la valeur de chaîne dont vous avez besoin.

17
GriffeyDog

Pour obtenir le diff en quelques secondes, vous pouvez utiliser ceci

select round(24 * 60 * 60* (TO_DATE('2017/02/17 9:32:25', 'YYYY/MM/DD HH:MI:SS') - TO_DATE('2017/02/17 8:30:30', 'YYYY/MM/DD HH:MI:SS'))) from dual;
2
ok2307