计算两个段之间的天数
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
,其中 Saturday
是 7th
,Sunday
是 1st
日,而 UNITED KINGDOM
(或我的国家 TURKEY
) 分别设置为 6th
和 7th
。
这是一种计算方法 - 不使用日历 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
下面有两个表格。我想计算天数,周一至周五仅在 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
,其中 Saturday
是 7th
,Sunday
是 1st
日,而 UNITED KINGDOM
(或我的国家 TURKEY
) 分别设置为 6th
和 7th
。
这是一种计算方法 - 不使用日历 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