2009-07-08 1 views
63

Ho una tabella come segue:Calcolare differenza tra 2 data/orari in Oracle SQL

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

Come posso calcuate la differenza in ore minuti e secondi (e possibilmente giorni) tra le due date in Oracle SQL ?

Grazie

+0

Quasi duplicati: http://stackoverflow.com/questions/9322935/subtracting-dates-in-oracle-number-or-interval-datatype –

risposta

93

È possibile sottrarre date in Oracle. Questo ti darà la differenza in giorni. Moltiplicare per 24 per ottenere ore e così via.

SQL> select oldest - creation from my_table; 

Se la data è memorizzata come dati carattere, è necessario prima convertirla in un tipo di data.

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 

Nota:

Questa risposta si applica alle date rappresentate dal tipo di dati Oracle DATE. Oracle ha anche un tipo di dati TIMESTAMP, che può anche rappresentare una data (con orario). Se si sottrae i valori TIMESTAMP, si ottiene INTERVAL; per estrarre valori numerici, utilizzare la funzione EXTRACT.

+2

C'è stato un cambiamento nel comportamento di Oracle ad un certo punto? Quando sottraggo una data da un'altra ottengo un tipo di dati 'INTERVAL', non un semplice float. –

+1

@JonofAllTrades: No, quando sottrai i valori di tipo 'DATE', ottieni il numero di giorni (come' NUMBER'). Tuttavia, se si sottrae i valori di 'TIMESTAMP', si ottiene' INTERVALDS'. Probabilmente stai lavorando con i valori di 'TIMESTAMP' e non di' DATE'. Ho modificato la risposta. – sleske

+0

Informazioni sulla nota - Entrambi i tipi di dati 'DATE' e' TIMESTAMP' hanno un componente orario (ore, minuti e secondi). 'TIMESTAMP' ha anche un componente dei secondi frazionari (e componenti potenzialmente del fuso orario). – MT0

5

È possibile utilizzare la funzione to_timestamp per convertire le date in timestamp ed eseguire un'operazione di sottrazione.

Qualcosa di simile:

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 
+6

quali unità darebbe? ore? millisecondi? scaglie? – skaffman

+0

Ho provato sia to_date che to_timestamp ed entrambi mi hanno dato una risposta in pochi giorni, arrotondato per difetto, quindi se la differenza è 1 ora ricevo una risposta di 0, moltiplicando questo per 24 restituisce 0. Ricevo la risposta corretta se scrivo nella data, ma non posso farlo per 25m righe. qualche idea? – Steve

+3

Utilizzando una sottrazione tra timestamp, si otterrebbe un altro timestamp in un formato come "DAYS HOUR: MINS: SECS.milisecs". Puoi troncare questo per ottenere il valore che ti serve – HyLian

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

Calcolare età da HIREDATE alla data di sistema del vostro computer

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

Spero che questo aiuti.

0

Questo conterà tempo tra di date:

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

Ecco un'altra opzione:

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; 
2
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); 
0
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 
9
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] 
    ); 

Questo vi darà tre colonne come giorni, ore e Minuti.

3

Si può anche provare questo:

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; 

Si visualizza il tempo in forma leggibile più umana, come: 00:01:34. Se hai bisogno anche di giorni puoi semplicemente aggiungere DD all'ultima stringa di formattazione.

0

in Oracle 11g

selezionare data_finale - start_date come day_diff da tablexxx Supponiamo che l'end_date start_date è definire nel tablexxx

1

Se vuoi qualcosa che sembra un po 'più semplice, prova questo per trovare eventi i n un tavolo che si è verificato negli ultimi 1 minuti:

Con questa voce è possibile giocare con i valori decimali fino ad ottenere il valore minuto desiderato. Il valore .0007 è di 1 minuto per quanto riguarda le cifre significative di sysdate. È possibile utilizzare multipli di che, per ottenere qualsiasi altro valore che si desidera:

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

risultato è 1 (minuto)

Poi si tratta di una semplice questione di verificare la presenza di

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

.0007 è hardcoded, per favore aggiusta – user1012506

0
(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