Berechnen Sie die Differenz zwischen 2 Datum / Uhrzeit in Oracle SQL


87

Ich habe eine Tabelle wie folgt:

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

Wie kann ich die Differenz in Stunden, Minuten und Sekunden (und möglicherweise Tagen) zwischen den beiden Daten in Oracle SQL berechnen?

Vielen Dank


Antworten:


116

Sie können Daten in Oracle subtrahieren. Dies gibt Ihnen den Unterschied in Tagen. Mit 24 multiplizieren, um Stunden zu erhalten, und so weiter.

SQL> select oldest - creation from my_table;

Wenn Ihr Datum als Zeichendaten gespeichert ist, müssen Sie es zuerst in einen Datumstyp konvertieren.

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

Hinweis :

Diese Antwort gilt für Daten, die durch den Oracle-Datentyp dargestellt werden DATE. Oracle hat auch einen Datentyp TIMESTAMP, der auch ein Datum (mit Uhrzeit) darstellen kann. Wenn Sie TIMESTAMPWerte subtrahieren , erhalten Sie eine INTERVAL; Verwenden Sie die EXTRACTFunktion , um numerische Werte zu extrahieren .


3
Hat sich das Verhalten von Oracle irgendwann geändert? Wenn ich ein Datum von einem anderen subtrahiere, erhalte ich einen INTERVALDatentyp, keinen einfachen Float.

2
@ JonofAllTrades: Nein, wenn Sie Werte vom Typ subtrahieren DATE, erhalten Sie die Anzahl der Tage (als NUMBER). Wenn Sie jedoch TIMESTAMPWerte subtrahieren , erhalten Sie INTERVALDS. Wahrscheinlich arbeiten Sie mit TIMESTAMPund nicht mit DATEWerten. Ich habe die Antwort bearbeitet.
Sleske

In Bezug auf Ihre Anmerkung - Sowohl die DATEund TIMESTAMPDatentypen haben eine Zeit (Stunden, Minuten und Sekunden) Komponente. TIMESTAMPhat auch eine Bruchteilsekunden-Zeitkomponente (und möglicherweise Zeitzonenkomponenten).
MT0

"Das gibt dir den Unterschied in Tagen." Können Sie bitte auf die Oracle-Dokumentation verlinken?
Roland

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 ;

Hoffe das hilft.



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] 
     );

Dadurch erhalten Sie drei Spalten als Tage, Stunden und Minuten.


7

Sie können dies auch versuchen:

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;

Es zeigt die Zeit in besser lesbarer Form an, z. B.: 00:01:34. Wenn Sie auch Tage benötigen, können Sie DD einfach zur letzten Formatierungszeichenfolge hinzufügen.


7

Mit der Funktion to_timestamp können Sie die Daten in Zeitstempel konvertieren und eine Subtraktionsoperation ausführen.

Etwas wie:

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

Ich habe sowohl den to_date als auch den to_timestamp ausprobiert und beide geben mir eine Antwort in Tagen, abgerundet. Wenn die Differenz 1 Stunde beträgt, erhalte ich eine Antwort von 0, multipliziert mit 24 ergibt 0. Ich erhalte die richtige Antwort, wenn ich tippe das Datum Uhrzeit, aber ich kann dies nicht für 25m Zeilen tun. Irgendwelche Gedanken?
Steve

3
Wenn Sie eine Subtraktion zwischen Zeitstempeln verwenden, erhalten Sie einen weiteren Zeitstempel in einem Format wie "DAYS HOUR: MINS: SECS.milisecs". Sie können dies abschneiden, um den Wert zu erhalten, den Sie benötigen
HyLian

6
Die Subtraktion zwischen Zeitstempeln gibt einen INTERVAL-Datentyp zurück. Mit der EXTRACT-Funktion können Sie verschiedene Teile eines Intervalls zurückgeben, z. B. Extrakt auswählen (Stunde ab (Zeitstempel '2009-12-31 14:00:00' - Zeitstempel '2009-12-31 12:15:00')) h von dual; Hinweis: Das zeigt nur den HOUR-Teil. Wenn der Unterschied also 1 Tag und 1 Stunde beträgt, wird 1 nicht 25 angezeigt.
Gary Myers

5

Berechnen Sie das Alter von HIREDATE bis zum Systemdatum Ihres Computers

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;

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 );

3

In Orakel 11g

SELECT end_date - start_date AS day_diff FROM tablexxx
suppose the starT_date end_date is define in the tablexxx

2

Wenn Sie zwei Daten aus ' your_table ' auswählen und das Ergebnis auch als einspaltige Ausgabe sehen möchten (z. B. ' Tage - hh: mm: ss '), können Sie so etwas verwenden. Zuerst können Sie das Intervall zwischen diesen beiden Daten berechnen und anschließend alle benötigten Daten aus diesem Intervall exportieren:

         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

Und das sollte Ihnen folgendes Ergebnis bringen: 0 Tage - 1:14:55


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 

1

Wenn Sie etwas möchten, das etwas einfacher aussieht, versuchen Sie dies, um Ereignisse in einer Tabelle zu finden, die in der letzten Minute aufgetreten sind:

Mit diesem Eintrag können Sie mit den Dezimalwerten herumspielen, bis Sie den gewünschten Minutenwert erhalten. Der Wert .0007 beträgt 1 Minute, was die signifikanten Ziffern des Systems betrifft. Sie können ein Vielfaches davon verwenden, um einen beliebigen anderen Wert zu erhalten:

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

Ergebnis ist 1 (Minute)

Dann ist es einfach zu überprüfen

select * from my_table where (sysdate - transdate) < .00071;

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 

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;  

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'"; 

0

Dies zählt die Zeit zwischen den Daten:

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

0

Hier ist eine weitere 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;

0

Einzelne Abfrage, die die Zeitdifferenz zweier Zeitstempelspalten zurückgibt:

select INS_TS, MAIL_SENT_TS, extract( hour from (INS_TS - MAIL_SENT_TS) ) timeDiff 
from MAIL_NOTIFICATIONS;

0

Wenn Sie eine Datumsverschiebung von der Verwendung von Tabelle und Spalte erhalten möchten.

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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.