【问题标题】:Count days between two segments计算两个段之间的天数
【发布时间】:2018-10-26 01:59:44
【问题描述】:

我在下面有两张桌子。我想计算周一至周五仅在 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

【问题讨论】:

  • 您要计算两个日期之间的天数?
  • 为什么需要第二张表?您“拥有”它,还是因为您认为它可能有助于解决问题而构建它?此外,您是否需要输出中的两列(包括和不包括雇佣日期)?一个还不够吗?

标签: sql oracle calendar between


【解决方案1】:

这是进行计算的一种方法 - 不使用日历表。唯一的输入数据来自您的第一个表(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

【讨论】:

    【解决方案2】:

    您可以使用以下例程(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
    

    附注整数值来自 to_char(&lt;date&gt;,'D') 取决于 NLS_TERRITORY 设置。在这里,我使用了AMERICA,其中Saturday7thSunday1st 日,而UNITED KINGDOM(或我的国家TURKEY)设置为6th7th分别。

    Rextester Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-26
      • 2019-09-27
      相关资源
      最近更新 更多