计算两个段之间的天数

Count days between two segments

下面有两个表格。我想计算天数,周一至周五仅在 Hire_dt 和雇用日期所在的日历月末之间。

表A

Hire_DT         Id
 09/26/2018     1

日历表:

Date         WorkDay(M-F)      EOM        WorkDay
09/26/2018     Wednesday       9/30/2018    1
09/27/2018     Thursday        09/30/2018   1
09/28/2018     Friday          09/30/2018   1
09/29/2018     Saturday        09/30/2018   0
09/30/2018     Sunday          09/30/2018   0

预期结果

Hire_dt        WorkDaysEndMonth   WorkDaysEndMonth --counting hire_dt
 09/26/2018         2                 3

您可以使用以下例程(其中 last_day 函数是一个伟大的贡献者):

SQL> alter session set NLS_TERRITORY="AMERICA";
SQL> create table TableA( ID int, Hire_DT date );
SQL> insert into TableA values(1,date'2018-09-26');

SQL> select sum(case when mod(to_char(myDate,'D'),7) <= 1 then 0 else 1 end )
         as "WorkDaysEndMonth"
       from 
       (
         select Hire_DT + level - 1 myDate
           from TableA
          where ID = 1
        connect by level <= last_day(Hire_DT) - Hire_DT + 1
       );

 WorkDaysEndMonth
 ----------------
        3

P.S。整数值来自 to_char(<date>,'D') 取决于 NLS_TERRITORY 设置。这里我使用 AMERICA,其中 Saturday7thSunday1st 日,而 UNITED KINGDOM(或我的国家 TURKEY) 分别设置为 6th7th

Rextester Demo

这是一种计算方法 - 不使用日历 table。唯一的输入数据来自您的第一个 table(ID 和 HIRE_DATE),我将其包含在 WITH 子句中(不是回答您问题的查询的一部分!)。其他一切都是计算出来的。我展示了如何计算包括雇佣日期在内的天数;如果您不需要,请在末尾减去 1。

TRUNC(<date>, 'iw')<date> 一周的星期一。该查询计算 EOM 周在星期一和 EOM 之间有多少天,但不超过 5 天(如果 EOM 可能是星期六或星期日)。它对 HIRE_DATE 进行了类似的计算,但它计算的是从星期一到 HIRE_DATE 不包括 HIRE_DATE 的天数。最后一部分是 HIRE_DATE 的星期一和 EOM 的星期一之间的每个完整周增加 5 天。

with
  sample_data(id, hire_date) as (
    select 1, to_date('09/26/2018', 'mm/dd/yyyy') from dual union all
    select 2, to_date('07/10/2018', 'mm/dd/yyyy') from dual
  )
select id, to_char(hire_date, 'Dy mm/dd/yyyy')                      as hire_date,
       to_char(eom, 'Dy mm/dd/yyyy')                                as eom,
       least(5, eom - eom_mon + 1) - least(5, hire_date - hire_mon)
       + (eom_mon - hire_mon) * 5 / 7                               as workdays
from   (
         select id, hire_date, last_day(hire_date) as eom,
                trunc(hire_date, 'iw')             as hire_mon,
                trunc(last_day(hire_date), 'iw')   as eom_mon
         from   sample_data
       )
;

        ID HIRE_DATE               EOM                       WORKDAYS
---------- ----------------------- ----------------------- ----------
         1 Wed 09/26/2018          Sun 09/30/2018                   3
         2 Tue 07/10/2018          Tue 07/31/2018                  16