Calculer la différence entre 2 dates / heures dans Oracle SQL

88

J'ai un tableau comme suit:

Filename - varchar
Creation Date - Date format dd/mm/yyyy hh24:mi:ss
Oldest cdr date - Date format dd/mm/yyyy hh24:mi:ss

Comment puis-je calculer la différence en heures, minutes et secondes (et éventuellement en jours) entre les deux dates dans Oracle SQL?

Merci

Steve
la source

Réponses:

118

Vous pouvez soustraire des dates dans Oracle. Cela vous donnera la différence en jours. Multipliez par 24 pour obtenir des heures, et ainsi de suite.

SQL> select oldest - creation from my_table;

Si votre date est stockée sous forme de données de caractère, vous devez d'abord la convertir en type de date.

SQL> select 24 * (to_date('2009-07-07 22:00', 'YYYY-MM-DD hh24:mi') 
             - to_date('2009-07-07 19:30', 'YYYY-MM-DD hh24:mi')) diff_hours 
       from dual;

DIFF_HOURS
----------
       2.5

Remarque :

Cette réponse s'applique aux dates représentées par le type de données Oracle DATE. Oracle a également un type de données TIMESTAMP, qui peut également représenter une date (avec l'heure). Si vous soustrayez des TIMESTAMPvaleurs, vous obtenez un INTERVAL; pour extraire des valeurs numériques, utilisez la EXTRACTfonction.

Thilo
la source
3
Y a-t-il eu un changement dans le comportement d'Oracle à un moment donné? Lorsque je soustrais une date d'une autre, j'obtiens un INTERVALtype de données, pas un simple flottant.
2
@JonofAllTrades: Non, lorsque vous soustrayez des valeurs de type DATE, vous obtenez le nombre de jours (en a NUMBER). Cependant, si vous soustrayez des TIMESTAMPvaleurs, vous obtenez INTERVALDS. Vous travaillez probablement avec TIMESTAMPet non avec des DATEvaleurs. J'ai édité la réponse.
sleske
Concernant votre note - Les types de données DATEet TIMESTAMPont tous deux un composant d'heure (heures, minutes et secondes). TIMESTAMPa également un composant de temps fractionnaire (et éventuellement des composants de fuseau horaire).
MT0
"Cela vous donnera la différence en jours." Pouvez-vous créer un lien vers la documentation Oracle s'il vous plaît?
Roland le
16
declare
strTime1 varchar2(50) := '02/08/2013 01:09:42 PM';
strTime2 varchar2(50) := '02/08/2013 11:09:00 PM';
v_date1 date := to_date(strTime1,'DD/MM/YYYY HH:MI:SS PM');
v_date2 date := to_date(strTime2,'DD/MM/YYYY HH:MI:SS PM');
difrence_In_Hours number;
difrence_In_minutes number;
difrence_In_seconds number;
begin
    difrence_In_Hours   := (v_date2 - v_date1) * 24;
    difrence_In_minutes := difrence_In_Hours * 60;
    difrence_In_seconds := difrence_In_minutes * 60;

    dbms_output.put_line(strTime1);        
    dbms_output.put_line(strTime2);
    dbms_output.put_line('*******');
    dbms_output.put_line('difrence_In_Hours  : ' || difrence_In_Hours);
    dbms_output.put_line('difrence_In_minutes: ' || difrence_In_minutes);
    dbms_output.put_line('difrence_In_seconds: ' || difrence_In_seconds);        
end ;

J'espère que cela t'aides.

Mohsen Heydari
la source
14
select 
    extract( day from diff ) Days, 
    extract( hour from diff ) Hours, 
    extract( minute from diff ) Minutes 
from (
        select (CAST(creationdate as timestamp) - CAST(oldcreationdate as timestamp)) diff   
        from [TableName] 
     );

Cela vous donnera trois colonnes en jours, heures et minutes.

Ishan Rastogi
la source
8

Vous pouvez également essayer ceci:

select to_char(to_date('1970-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')+(end_date - start_date),'hh24:mi:ss')
       as run_time from some_table;

Il affiche l'heure sous une forme plus lisible par l'homme, comme: 00:01:34. Si vous avez besoin également de jours, vous pouvez simplement ajouter DD à la dernière chaîne de formatage.

RLapinski
la source
7

Vous pouvez utiliser la fonction to_timestamp pour convertir les dates en horodatages et effectuer une opération de soustraction.

Quelque chose comme:

SELECT 
TO_TIMESTAMP ('13.10.1990 00:00:00','DD.MM.YYYY HH24:MI:SS')  - 
TO_TIMESTAMP ('01.01.1990:00:10:00','DD.MM.YYYY:HH24:MI:SS')
FROM DUAL
HyLian
la source
J'ai essayé à la fois le to_date et le to_timestamp et les deux me donnent une réponse en jours, arrondie à l'inférieur, donc si la différence est de 1 heure, je reçois une réponse de 0, multiplier cela par 24 donne 0. Je reçois la bonne réponse si je tape l'heure de la date mais je ne peux pas faire cela pour 25m de lignes. Des pensées?
Steve
3
En utilisant une soustraction entre les horodatages, il vous renverrait un autre horodatage dans un format comme "DAYS HOUR: MINS: SECS.milisecs". Vous pouvez tronquer ceci pour obtenir la valeur dont vous avez besoin
HyLian
6
La soustraction entre les horodatages renvoie un type de données INTERVAL. Vous pouvez utiliser la fonction EXTRACT pour renvoyer diverses parties d'un intervalle, par exemple sélectionner l'extrait (heure de (horodatage '2009-12-31 14:00:00' - horodatage '2009-12-31 12:15:00')) hr de double; Remarque: Cela ne montre que la partie HOUR, donc si la différence est de 1 jour et 1 heure, cela affichera 1 et non 25.
Gary Myers
5

Calculez l'âge du HIREDATE à la date système de votre ordinateur

SELECT HIREDATE||'        '||SYSDATE||'       ' ||
TRUNC(MONTHS_BETWEEN(SYSDATE,HIREDATE)/12) ||' YEARS '||
TRUNC((MONTHS_BETWEEN(SYSDATE,HIREDATE))-(TRUNC(MONTHS_BETWEEN(SYSDATE,HIREDATE)/12)*12))||
'MONTHS' AS "AGE  "  FROM EMP;
SOLEIL BEHERA
la source
3
select days||' '|| time from (
SELECT to_number( to_char(to_date('1','J') +
    (CLOSED_DATE - CREATED_DATE), 'J') - 1)  days,
   to_char(to_date('00:00:00','HH24:MI:SS') +
      (CLOSED_DATE - CREATED_DATE), 'HH24:MI:SS') time
 FROM  request  where REQUEST_ID=158761088 );
Amitt Gaur
la source
3

Dans oracle 11g

SELECT end_date - start_date AS day_diff FROM tablexxx
suppose the starT_date end_date is define in the tablexxx
Michael
la source
2

Si vous sélectionnez deux dates dans « votre_table » et que vous voulez aussi voir le résultat sous la forme d'une sortie de colonne unique (par exemple, « jours - hh: mm: ss »), vous pouvez utiliser quelque chose comme ceci. Vous pouvez d'abord calculer l'intervalle entre ces deux dates, puis exporter toutes les données dont vous avez besoin à partir de cet intervalle:

         select     extract (day from numtodsinterval (second_date
                                                   - add_months (created_date,
                                                                 floor (months_between (second_date,created_date))),
                                                   'day'))
             || ' days - '
             || extract (hour from numtodsinterval (second_date
                                                    - add_months (created_date,
                                                                  floor (months_between (second_date,created_date))),
                                                    'day'))
             || ':'
             || extract (minute from numtodsinterval (second_date
                                                      - add_months (created_date,
                                                                    floor (months_between (second_date, created_date))),
                                                      'day'))
             || ':'
             || extract (second from numtodsinterval (second_date
                                                      - add_months (created_date,
                                                                    floor (months_between (second_date, created_date))),
                                                      'day'))
     from    your_table

Et cela devrait vous donner un résultat comme celui-ci: 0 jours - 1:14:55

Nik
la source
1
select (floor(((DATE2-DATE1)*24*60*60)/3600)|| ' : ' ||floor((((DATE2-DATE1)*24*60*60) -floor(((DATE2-DATE1)*24*60*60)/3600)*3600)/60)|| '  ' ) as time_difference from TABLE1 

la source
1

Si vous voulez quelque chose qui semble un peu plus simple, essayez ceci pour rechercher des événements dans une table qui se sont produits au cours de la dernière minute:

Avec cette entrée, vous pouvez jouer avec les valeurs décimales jusqu'à ce que vous obteniez la valeur minute souhaitée. La valeur .0007 se trouve être 1 minute en ce qui concerne les chiffres significatifs de la date système. Vous pouvez utiliser des multiples de cela pour obtenir toute autre valeur que vous souhaitez:

select (sysdate - (sysdate - .0007)) * 1440 from dual;

Le résultat est 1 (minute)

Ensuite, il est simple de vérifier

select * from my_table where (sysdate - transdate) < .00071;
Cliff Adams
la source
1
(TO_DATE(:P_comapre_date_1, 'dd-mm-yyyy hh24:mi') - TO_DATE(:P_comapre_date_2, 'dd-mm-yyyy hh24:mi'))*60*60*24 sum_seconds,
         (TO_DATE(:P_comapre_date_1, 'dd-mm-yyyy hh24:mi') - TO_DATE(:P_comapre_date_2, 'dd-mm-yyyy hh24:mi'))*60*24 sum_minutes,
         (TO_DATE(:P_comapre_date_1, 'dd-mm-yyyy hh24:mi') - TO_DATE(:P_comapre_date_2, 'dd-mm-yyyy hh24:mi'))*24 sum_hours,
         (TO_DATE(:P_comapre_date_1, 'dd-mm-yyyy hh24:mi') - TO_DATE(:P_comapre_date_2, 'dd-mm-yyyy hh24:mi')) sum_days 
user1012506
la source
1
select to_char(actual_start_date,'DD-MON-YYYY hh24:mi:ss') start_time,
to_char(actual_completion_date,'DD-MON-YYYY hh24:mi:ss') end_time,
floor((actual_completion_date-actual_start_date)*24*60)||'.'||round(mod((actual_completion_date-actual_start_date)*24*60*60,60)) diff_time
from fnd_concurrent_requests 
order by request_id desc;  
user12423961
la source
0
$sql="select bsp_bp,user_name,status,
to_char(ins_date,'dd/mm/yyyy hh12:mi:ss AM'),
to_char(pickup_date,'dd/mm/yyyy hh12:mi:ss AM'),
trunc((pickup_date-ins_date)*24*60*60,2),message,status_message 
from valid_bsp_req where id >= '$id'"; 
Dan D.
la source
0

Cela comptera le temps entre les dates:

SELECT
  (TO_CHAR( TRUNC (ROUND(((sysdate+1) - sysdate)*24,2))*60,'999999')
  +
  TO_CHAR(((((sysdate+1)-sysdate)*24)- TRUNC(ROUND(((sysdate+1) - sysdate)*24,2)))/100*60 *100, '09'))/60
FROM dual
gpio
la source
0

Voici une autre option:

with tbl_demo AS
    (SELECT TO_DATE('11/26/2013 13:18:50', 'MM/DD/YYYY HH24:MI:SS') dt1
   , TO_DATE('11/28/2013 21:59:12', 'MM/DD/YYYY HH24:MI:SS') dt2 
     FROM dual)
SELECT dt1
     , dt2
     , round(dt2 - dt1,2) diff_days
     , round(dt2 - dt1,2)*24 diff_hrs
     , numtodsinterval((dt2 - dt1),'day') diff_dd_hh_mm_ss
  from tbl_demo;

la source
0

Requête unique qui renverra le décalage horaire de deux colonnes d'horodatage:

select INS_TS, MAIL_SENT_TS, extract( hour from (INS_TS - MAIL_SENT_TS) ) timeDiff 
from MAIL_NOTIFICATIONS;
Sandeep Raul
la source
0

Si vous voulez que la date diffère d'utiliser la table et la colonne.

SELECT TO_DATE( TO_CHAR(COLUMN_NAME_1, 'YYYY-MM-DD'), 'YYYY-MM-DD') - 
       TO_DATE(TO_CHAR(COLUMN_NAME_2, 'YYYY-MM-DD') , 'YYYY-MM-DD')  AS DATEDIFF       
FROM TABLE_NAME;
Nurullah
la source