簡體   English   中英

Oracle SQL 小時時差

[英]Oracle SQL Time Difference in hours

我試圖找到一種方法來比較兩個日期的假期時間。

目前下面的查詢不包括假期並返回工作時間。 我正在努力以另一種方式得到它。 只是返回開始日期和結束日期之間的假期小時數。

如果開始日期是 15-04-22 16:00 並且它是一個假期,那么查詢應該只返回 b/w 16:00 - 18:00 的小時數。 (工作時間為7:00-18:00)


create table holidays_tb(
holiday_date date
);

insert into holidays_tb values (TO_DATE('15/04/2022', 'DD/MM/YYYY')); 
insert into holidays_tb values (TO_DATE('18/04/2022', 'DD/MM/YYYY'));


declare
v_st_date date;
v_end_date date;
return_val number;
begin
v_st_date := TO_DATE('13/04/2022 09:55:52', 'DD/MM/YYYY HH24:MI:SS'); 
v_end_date := TO_DATE('19/04/2022 16:30:00', 'DD/MM/YYYY HH24:MI:SS'); 
with all_days as
            (select trunc(v_st_date) + level - 1 as a_dt
            from dual
              connect by level <= 1 + (v_end_date - v_st_date)
            minus
            select holiday_date from holidays_tb
            )
          select sum (11)
          into return_val
          from all_days
          where TO_CHAR ( a_dt , 'Dy') NOT IN ('Sat', 'Sun');
dbms_output.put_line(  return_val );        
end;

現在已經堅持了幾個多小時:|

您可以使用以下方法獲取假期小時數:

DECLARE
  v_st_date  date := DATE '2022-04-13' + INTERVAL '0 09:55:52' DAY TO SECOND;
  v_end_date date := DATE '2022-04-19' + INTERVAL '0 16:30:00' DAY TO SECOND;
  v_work_day_start INTERVAL DAY(0) TO SECOND(0) := INTERVAL '0 07:00:00' DAY TO SECOND;
  v_work_day_end   INTERVAL DAY(0) TO SECOND(0) := INTERVAL '0 18:00:00' DAY TO SECOND;
  v_hours NUMBER := EXTRACT(HOUR FROM v_work_day_end - v_work_day_start)
                  + EXTRACT(MINUTE FROM v_work_day_end - v_work_day_start)/60
                  + EXTRACT(MINUTE FROM v_work_day_end - v_work_day_start)/3600;
  v_holiday NUMBER;
  return_val number;
BEGIN
  SELECT SUM(
           LEAST(holiday_date + v_work_day_end, v_end_date)
           - GREATEST(holiday_date + v_work_day_start, v_st_date)
         ) * 24
  INTO   v_holiday
  FROM   holidays_tb
  WHERE  holiday_date BETWEEN TRUNC(v_st_date) AND v_end_date
  AND    holiday_date - TRUNC(holiday_date, 'IW') < 5;

  DBMS_OUTPUT.PUT_LINE( v_holiday );
END;
/

其中,對於樣本數據,輸出22


此外,您不需要使用遞歸查詢來獲取天數,可以使用以下方法直接計算:

DECLARE
  v_st_date  date := DATE '2022-04-13' + INTERVAL '0 09:55:52' DAY TO SECOND;
  v_end_date date := DATE '2022-04-19' + INTERVAL '0 16:30:00' DAY TO SECOND;
  v_work_day_start INTERVAL DAY(0) TO SECOND(0) := INTERVAL '0 07:00:00' DAY TO SECOND;
  v_work_day_end   INTERVAL DAY(0) TO SECOND(0) := INTERVAL '0 18:00:00' DAY TO SECOND;
  v_hours NUMBER := EXTRACT(HOUR FROM v_work_day_end - v_work_day_start)
                  + EXTRACT(MINUTE FROM v_work_day_end - v_work_day_start)/60
                  + EXTRACT(MINUTE FROM v_work_day_end - v_work_day_start)/3600;
  v_holiday NUMBER;
  return_val number;
BEGIN
  SELECT SUM(
           LEAST(holiday_date + v_work_day_end, v_end_date)
           - GREATEST(holiday_date + v_work_day_start, v_st_date)
         ) * 24
  INTO   v_holiday
  FROM   holidays_tb
  WHERE  holiday_date BETWEEN TRUNC(v_st_date) AND v_end_date
  AND    holiday_date - TRUNC(holiday_date, 'IW') < 5;

  return_val :=
    -- Full weeks
    (TRUNC(v_end_date, 'IW') - TRUNC(v_st_date, 'IW')) * 5 / 7 * v_hours
    -- Full days before in start week
    - LEAST(TRUNC(v_st_date) - TRUNC(v_st_date, 'IW'), 5) * v_hours
    -- Part days before in start week
    - CASE
      WHEN v_st_date - TRUNC(v_st_date, 'IW') < 5
      THEN LEAST(
             GREATEST(
               (v_st_date - (TRUNC(v_st_date) + v_work_day_start))* 24,
               0
             ),
             v_hours
           )
      ELSE 0
      END
    -- End full days
    + LEAST(TRUNC(v_end_date) - TRUNC(v_end_date, 'IW'), 5) * v_hours
    -- End part days
    + CASE
      WHEN v_end_date - TRUNC(v_end_date, 'IW') < 5
      THEN LEAST(
             GREATEST(
               (v_end_date - (TRUNC(v_end_date) + v_work_day_start))* 24,
               0
             ),
             v_hours
           )
      ELSE 0
      END
    -- Holiday hours
    - v_holiday;
    
  DBMS_OUTPUT.PUT_LINE( return_val );        
END;
/

輸出: 28.5689 (3 天 33 小時,結束時減去 1.5 小時,開始時將近 3 小時)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM