Oracle查询以获取两个日期之间的工作日数

时间:2019-01-25 17:27:46

标签: sql oracle date oracle11g

我们正在使用Oracle 11。

在CASE WHEN语句中,我需要检查两个日期之间的天数是否大于3个工作日(因此不包括周末和节假日)。

所以,如果

Date1 = 1/21/19(星期一)

Date2 = 1/18/19(星期五)

日期1和日期2之间的工作日数是1天,而不是3天。

CASE WHEN TO_DATE(SETTLEMENT_DATE, 'YYYY-MM-DD') - TO_DATE(TRADE_DATE, 
'YYYY-MM-DD')  > 3  THEN 0  --> this includes weekend and holidays
WHEN CODE = 1 THEN 1
WHEN CODE =2 THEN 2
ELSE 3
END AS MyColumn

谢谢。

2 个答案:

答案 0 :(得分:0)

您可以创建将conditional aggregation用作

的函数。
SQL> alter session set NLS_TERRITORY="AMERICA"
SQL> create or replace function get_working_days( 
                                             i_settlement_date tab.settlement_date%type, 
                                             i_trade_date      tab.trade_date%type
                                           ) return pls_integer is
  o_working_days  pls_integer;                                         
begin
  select nvl(sum(case when
              to_char(trade_date + level,'Dy') in ('Sat','Sun') 
             then 0
             else 1
             end ),0)
  into o_working_days
  from tab
 where settlement_date >= trade_date
 connect by level <= i_settlement_date - i_trade_date + 1;

 return o_working_days;
end; 

获取两个日期(包括两个边界日期)之间的工作日。

即它会为您的情况返回2,包括mondayfriday

编辑::如果您不想创建函数,请使用以下查询与替换变量&i_settlement_date&i_trade_date

  select nvl(sum(case when
              to_char(trade_date + level,'Dy') in ('Sat','Sun') 
             then 0
             else 1
             end ),0) as working_days
  from tab
 where settlement_date >= trade_date
 connect by level <= &i_settlement_date - &i_trade_date + 1;

,并在出现提示时分别将样本值输入为date'2019-01-21'date'2019-01-18'

答案 1 :(得分:0)

您不需要使用分层查询,并且可以独立于NLS设置使用TRUNC( date_value, 'IW' )进行查询,以查找ISO星期的开始,始终是星期一。

( TRUNC( end_date, 'IW' ) - TRUNC( start_date, 'IW' ) ) * 5 / 7

将找到包含开始日期的ISO周开始与包含结束日期的ISO周开始之间的工作天数。

然后只需添加最后一周的工作日:

+ LEAST( TRUNC( end_date   ) - TRUNC( end_date,   'IW' ) + 1, 5 )

并减去开始日期之前的第一个ISO周的天数:

- LEAST( TRUNC( start_date ) - TRUNC( start_date, 'IW' ), 5 )

哪个放在一起会给出:

Oracle设置

CREATE TABLE table_name ( start_date, end_date ) AS
SELECT DATE '2018-12-30' + LEVEL, DATE '2019-01-10' 
FROM DUAL
CONNECT BY LEVEL <= 11

查询

SELECT TO_CHAR( start_date, 'YYYY-MM-DD "("DY")"') AS start_date,

       ( TRUNC( end_date, 'IW' ) - TRUNC( start_date, 'IW' ) ) * 5 / 7
       + LEAST( TRUNC( end_date   ) - TRUNC( end_date,   'IW' ) + 1, 5 )
       - LEAST( TRUNC( start_date ) - TRUNC( start_date, 'IW' ), 5 )
         AS Num_Week_Days
FROM   table_name;

输出

START_DATE       | NUM_WEEK_DAYS
:--------------- | ------------:
2018-12-31 (MON) |             9
2019-01-01 (TUE) |             8
2019-01-02 (WED) |             7
2019-01-03 (THU) |             6
2019-01-04 (FRI) |             5
2019-01-05 (SAT) |             4
2019-01-06 (SUN) |             4
2019-01-07 (MON) |             4
2019-01-08 (TUE) |             3
2019-01-09 (WED) |             2
2019-01-10 (THU) |             1

db <>提琴here