คำนวณความแตกต่างระหว่าง 2 วันที่ / เวลาใน Oracle SQL


89

ฉันมีตารางดังนี้:

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

ฉันจะคำนวณความแตกต่างเป็นชั่วโมงนาทีและวินาที (และอาจเป็นวัน) ระหว่างวันที่สองวันใน Oracle SQL ได้อย่างไร

ขอบคุณ


ใกล้ซ้ำกัน: stackoverflow.com/questions/9322935/…

คำตอบ:


120

คุณสามารถแทนที่วันที่ใน Oracle สิ่งนี้จะให้ความแตกต่างในแต่ละวัน คูณด้วย 24 เพื่อรับชั่วโมงและอื่น ๆ

SQL> select oldest - creation from my_table;

หากวันที่ของคุณจัดเก็บเป็นข้อมูลอักขระคุณต้องแปลงเป็นประเภทวันที่ก่อน

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

หมายเหตุ :

DATEคำตอบนี้มีผลบังคับใช้วันที่แสดงโดยชนิดข้อมูลของออราเคิล Oracle ยังมีประเภทข้อมูลTIMESTAMPซึ่งสามารถแสดงวันที่ (พร้อมเวลา) หากคุณลบTIMESTAMPค่าคุณจะได้รับINTERVAL; ในการแยกค่าตัวเลขให้ใช้EXTRACTฟังก์ชัน


3
มีการเปลี่ยนแปลงพฤติกรรมของ Oracle ในบางจุดหรือไม่? เมื่อฉันลบวันที่หนึ่งออกจากอีกวันหนึ่งฉันจะได้INTERVALชนิดข้อมูลไม่ใช่ลอยธรรมดา

2
@JonofAllTrades: ไม่เมื่อคุณลบค่าของประเภทDATEคุณจะได้รับจำนวนวัน (เป็น a NUMBER) แต่ถ้าคุณลบค่าคุณจะได้รับTIMESTAMP INTERVALDSคุณอาจกำลังทำงานกับTIMESTAMPและไม่ใช่DATEค่านิยม ฉันแก้ไขคำตอบ
sleske

เกี่ยวกับบันทึกย่อของคุณ - ทั้งประเภทDATEและTIMESTAMPข้อมูลมีองค์ประกอบเวลา (ชั่วโมงนาทีและวินาที) TIMESTAMPนอกจากนี้ยังมีส่วนประกอบของเวลาเสี้ยววินาที (และส่วนประกอบของเขตเวลาที่อาจเกิดขึ้น)
MT0

"สิ่งนี้จะให้ความแตกต่างในแต่ละวัน" ขอลิงค์ไปยังเอกสาร Oracle ได้ไหม
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 ;

หวังว่านี่จะช่วยได้


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

ซึ่งจะให้คอลัมน์สามคอลัมน์เป็นวันชั่วโมงและนาที


8

คุณสามารถลองสิ่งนี้:

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;

จะแสดงเวลาในรูปแบบที่มนุษย์อ่านได้มากขึ้นเช่น 00:01:34 น. หากคุณต้องการวันคุณสามารถเพิ่ม DD ในสตริงการจัดรูปแบบล่าสุดได้


7

คุณสามารถใช้ฟังก์ชัน to_timestamp เพื่อแปลงวันที่เป็นการประทับเวลาและดำเนินการแทนที่

สิ่งที่ต้องการ:

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

ฉันได้ลองทั้ง to_date และ to_timestamp แล้วและทั้งคู่ให้คำตอบเป็นวันปัดเศษลงดังนั้นหากความแตกต่างคือ 1 ชั่วโมงฉันจะได้รับคำตอบเป็น 0 การคูณด้วย 24 จะให้ 0 ฉันได้รับคำตอบที่ถูกต้องหากฉันพิมพ์ วันเวลา แต่ทำไม่ได้สำหรับ 25m แถว ความคิดใด ๆ ?
Steve

3
การใช้การย่อยระหว่างการประทับเวลาจะส่งคืนการประทับเวลาอื่นในรูปแบบเช่น "DAYS HOUR: MINS: SECS.milisecs" คุณสามารถตัดทอนสิ่งนี้เพื่อให้ได้ค่าที่คุณต้องการ
HyLian

6
การลบระหว่างการประทับเวลาจะส่งกลับประเภทข้อมูล INTERVAL คุณสามารถใช้ฟังก์ชัน EXTRACT เพื่อส่งคืนส่วนต่างๆของช่วงเวลาเช่นเลือกสารสกัด (ชั่วโมงจาก (ประทับเวลา '2009-12-31 14:00:00' - ประทับเวลา '2009-12-31 12:15:00')) ชม. จากคู่; หมายเหตุ: แสดงเฉพาะส่วนชั่วโมงดังนั้นหากความแตกต่างคือ 1 วันกับ 1 ชั่วโมงจะแสดง 1 ไม่ใช่ 25
Gary Myers

5

คำนวณอายุจาก HIREDATE ถึงวันที่ระบบของคอมพิวเตอร์ของคุณ

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


2

หากคุณเลือกวันที่สองวันจาก ' your_table ' และต้องการให้ผลลัพธ์เป็นคอลัมน์เดียวเช่นกัน (เช่น ' days - hh: mm: ss ') คุณสามารถใช้สิ่งนี้ได้ ขั้นแรกคุณสามารถคำนวณช่วงเวลาระหว่างวันที่สองวันนี้และหลังจากนั้นส่งออกข้อมูลทั้งหมดที่คุณต้องการจากช่วงเวลานั้น:

         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

และนั่นควรให้ผลลัพธ์ดังนี้: 0 วัน - 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

หากคุณต้องการสิ่งที่ดูเรียบง่ายกว่านี้ให้ลองค้นหาเหตุการณ์ในตารางที่เกิดขึ้นใน 1 นาทีที่ผ่านมา:

ด้วยรายการนี้คุณสามารถใช้ค่าทศนิยมจนกว่าคุณจะได้ค่านาทีที่คุณต้องการ ค่า. 0007 จะเป็น 1 นาทีเท่าที่ตัวเลขนัยสำคัญ sysdate เกี่ยวข้อง คุณสามารถใช้ทวีคูณเพื่อรับค่าอื่น ๆ ที่คุณต้องการ:

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

ผลลัพธ์คือ 1 (นาที)

จากนั้นจึงเป็นเรื่องง่ายที่จะตรวจสอบ

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

การดำเนินการนี้จะนับเวลาระหว่างวันที่:

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

นี่เป็นอีกทางเลือกหนึ่ง:

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

แบบสอบถามเดียวที่จะส่งกลับความแตกต่างของเวลาของคอลัมน์การประทับเวลาสองคอลัมน์:

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

0

ถ้าคุณต้องการให้วันที่เลื่อนจากการใช้ตารางและคอลัมน์

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;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.