2009-07-08 102 views
63

Tengo una tabla de la siguiente manera:Calcular la diferencia entre el 2 fecha/horas en 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 

Como puedo calcuate la diferencia en horas minutos y segundos (y posiblemente días) entre las dos fechas en Oracle SQL ?

Gracias

+0

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

Respuesta

93

Puede sustraer las fechas en Oracle. Esto te dará la diferencia en días. Multiplique por 24 para obtener horas, y así sucesivamente.

SQL> select oldest - creation from my_table; 

Si su fecha se almacena como datos de caracteres, primero debe convertirla en un tipo de fecha.

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:

Esta respuesta se aplica a las fechas representadas por el tipo de datos de Oracle DATE. Oracle también tiene un tipo de datos TIMESTAMP, que también puede representar una fecha (con el tiempo). Si resta valores TIMESTAMP, obtiene un INTERVAL; para extraer valores numéricos, use la función EXTRACT.

+2

¿Ha habido algún cambio en el comportamiento de Oracle en algún momento? Cuando restamos una fecha de otra obtengo un tipo de datos 'INTERVAL', no un simple flotante. –

+1

@JonofAllTrades: No, cuando resta valores de tipo 'DATE', obtiene el número de días (como' NÚMERO '). Sin embargo, si resta valores 'TIMESTAMP', obtiene' INTERVALDS'. Probablemente estés trabajando con los valores 'TIMESTAMP' y no' DATE'. Edité la respuesta. – sleske

+0

Acerca de su nota: los tipos de datos 'DATE' y' TIMESTAMP' tienen un componente de tiempo (horas, minutos y segundos). 'TIMESTAMP' también tiene un componente de tiempo de segundos fraccionarios (y componentes de zona horaria potencialmente). – MT0

5

Puede usar la función to_timestamp para convertir las fechas en timestamps y realizar una operación de resta.

Algo así como:

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

¿Qué unidades le daría esto? horas? milisegundos? astillas? – skaffman

+0

He intentado ambos to_date y to_timestamp y ambos me dan una respuesta en días, redondeada así que si la diferencia es de 1 hora, recibo una respuesta de 0, multiplicando esto por 24 da 0. Recibo la respuesta correcta si escribo en el tiempo de fecha pero no puedo hacer esto para 25m filas. ¿Alguna idea? – Steve

+3

Utilizando una sustracción entre las marcas de tiempo, le devolverá otra marca de tiempo en un formato como "HORAS DE DÍAS: MINS: SECS.milisecs". Puede truncar esto para obtener el valor que necesita – 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

Calcular la edad de HIREDATE hasta la fecha del sistema de su ordenador

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 ; 

Espero que esto ayude.

0

Esto contar el tiempo entre dos fechas:

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

Aquí hay otra opción:

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

Esto le dará tres columnas como días, horas y Minutos.

3

También puede probar esto:

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; 

Se muestra el tiempo en forma legible más humano, como: 00:01:34. Si también necesita días, simplemente puede agregar DD a la última cadena de formato.

0

en Oracle 11g

seleccione fecha_final - fecha_inicial como day_diff de tablexxx Supongamos que el fecha_final Fecha_inicial es definir en el tablexxx

1

Si quieres algo que parezca un poco más simple, prueba esto para encontrar eventos i n una tabla que ocurrió en el pasado 1 minuto:

Con esta entrada puede virar con los valores decimales hasta que obtenga el valor de minuto que desea. El valor .0007 pasa a ser de 1 minuto en lo que respecta a los dígitos significativos de sysdate. Se puede utilizar múltiplos de eso para conseguir cualquier otro valor que desee:

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

resultado es 1 (minutos)

Entonces es un asunto sencillo para comprobar si hay

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

.0007 está codificado, por favor corrige – 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 
Cuestiones relacionadas