Tính toán chênh lệch giữa 2 ngày / lần trong Oracle SQL


88

Tôi có một bảng như sau:

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

Làm cách nào tôi có thể tính toán sự khác biệt về giờ phút và giây (và có thể cả ngày) giữa hai ngày trong Oracle SQL?

Cảm ơn


Câu trả lời:


118

Bạn có thể trừ ngày tháng trong Oracle. Điều này sẽ cung cấp cho bạn sự khác biệt trong ngày. Nhân với 24 để được số giờ, v.v.

SQL> select oldest - creation from my_table;

Nếu ngày của bạn được lưu trữ dưới dạng dữ liệu ký tự, trước tiên bạn phải chuyển đổi nó thành kiểu ngày tháng.

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

Ghi chú :

Câu trả lời này áp dụng cho các ngày được biểu thị bằng kiểu dữ liệu Oracle DATE. Oracle cũng có một kiểu dữ liệu TIMESTAMP, kiểu này cũng có thể đại diện cho một ngày tháng (với thời gian). Nếu bạn trừ TIMESTAMPcác giá trị, bạn nhận được một INTERVAL; để trích xuất các giá trị số, hãy sử dụng EXTRACThàm.


3
Có sự thay đổi nào trong hành vi của Oracle vào một thời điểm nào đó không? Khi tôi trừ một ngày cho một ngày khác, tôi nhận được một INTERVALkiểu dữ liệu, không phải là một số thực đơn giản.

2
@JonofAllTrades: Không, khi bạn trừ các giá trị của kiểu DATE, bạn sẽ nhận được số ngày (dưới dạng a NUMBER). Tuy nhiên, nếu bạn trừ TIMESTAMPcác giá trị, bạn nhận được INTERVALDS. Có lẽ bạn đang làm việc với TIMESTAMPchứ không phải DATEcác giá trị. Tôi đã chỉnh sửa câu trả lời.
sleske

Về ghi chú của bạn - Cả kiểu dữ liệu DATETIMESTAMPkiểu đều có thành phần thời gian (giờ, phút và giây). TIMESTAMPcũng có thành phần thời gian giây phân số (và các thành phần có thể là múi giờ).
MT0

"Điều này sẽ mang lại cho bạn sự khác biệt trong ngày." Bạn có thể liên kết đến tài liệu Oracle được không?
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 ;

Hi vọng điêu nay co ich.


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

Điều này sẽ cung cấp cho bạn ba cột là Ngày, Giờ và Phút.


8

Bạn cũng có thể thử điều này:

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;

Nó hiển thị thời gian ở dạng con người dễ đọc hơn, như: 00:01:34. Nếu bạn cần thêm ngày, bạn có thể chỉ cần thêm DD vào chuỗi định dạng cuối cùng.


7

Bạn có thể sử dụng hàm to_timestamp để chuyển đổi ngày tháng thành dấu thời gian và thực hiện thao tác rút ngắn.

Cái gì đó như:

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

Tôi đã thử cả to_date và to_timestamp và cả hai đều cho tôi câu trả lời tính theo ngày, được làm tròn xuống vì vậy nếu sự khác biệt là 1 giờ, tôi nhận được câu trả lời là 0, nhân với 24 sẽ được 0. Tôi nhận được câu trả lời chính xác nếu nhập ngày giờ nhưng tôi không thể làm điều này cho 25 triệu hàng. Có suy nghĩ gì không?
Steve

3
Sử dụng một phân số giữa các dấu thời gian, nó sẽ trả lại cho bạn một dấu thời gian khác ở định dạng như "DAYS HOUR: MINS: SECS.milisecs". Bạn có thể TRUNC này để có được những giá trị mà bạn cần
HyLian

6
Phép trừ giữa các dấu thời gian trả về một kiểu dữ liệu INTERVAL. Bạn có thể sử dụng hàm EXTRACT để trả về các phần khác nhau của một khoảng thời gian, ví dụ như chọn trích xuất (giờ từ (dấu thời gian '2009-12-31 14:00:00' - dấu thời gian '2009-12-31 12:15:00')) hr từ kép; Lưu ý: Điều đó chỉ hiển thị phần GIỜ, vì vậy nếu sự khác biệt là 1 ngày và 1 giờ, phần này sẽ hiển thị 1 không phải 25.
Gary Myers

5

Tính tuổi từ HIREDATE đến ngày hệ thống của máy tính của bạn

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 oracle 11g

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

2

Nếu bạn chọn hai ngày từ ' your_table ' và muốn xem kết quả dưới dạng đầu ra một cột (ví dụ: ' days - hh: mm: ss '), bạn có thể sử dụng một cái gì đó như thế này. Trước tiên, bạn có thể tính toán khoảng thời gian giữa hai ngày này và sau đó xuất tất cả dữ liệu bạn cần từ khoảng thời gian đó:

         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

Và điều đó sẽ cho bạn kết quả như thế này: 0 ngày - 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

Nếu bạn muốn thứ gì đó trông đơn giản hơn một chút, hãy thử cách này để tìm các sự kiện trong bảng đã xảy ra trong 1 phút qua:

Với mục nhập này, bạn có thể tìm kiếm các giá trị thập phân cho đến khi bạn nhận được giá trị phút mà bạn muốn. Giá trị .0007 xảy ra là 1 phút khi có liên quan đến các chữ số có nghĩa của ngày mã hóa. Bạn có thể sử dụng bội số đó để nhận bất kỳ giá trị nào khác mà bạn muốn:

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

Kết quả là 1 (phút)

Sau đó, nó là một vấn đề đơn giản để kiểm tra

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

Điều này sẽ tính thời gian giữa các ngày:

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

Đây là một tùy chọn khác:

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

Một truy vấn sẽ trả về chênh lệch thời gian của hai cột dấu thời gian:

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

0

Nếu bạn muốn hoãn ngày sử dụng bảng và cột.

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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.