【问题标题】:Finding no. of working days in a month till sysdate/ today's date is it is current month找不到。一个月的工作日到 sysdate/今天的日期是当前月份
【发布时间】:2017-05-23 13:08:52
【问题描述】:

我正在使用以下查询来找出一个月中不包括周末的工作日数

select payroll_id as payrollId,
(select count(*) 
from ( select rownum rnum 
from all_objects 
where rownum <= to_date(to_char(last_day(to_date('01-'||'MAY'||'2017','DD-MM-YYYY')),'DD')||'MAY'||'2017','DD-MM-YYYY') - to_date('01-'||'MAY'||'2017','DD-MM-YYYY')+1 ) 
where to_char( to_date('01-'||'MAY'||'2017','DD-MM-YYYY')+rnum-1, 'DY' ) 
not in ( 'SAT', 'SUN' )) - (select count(*) from admin_holiday where to_char(holiday_date,'DD-MON-YYYY') like '%-MAY-2017%' and holiday_type_id=1) days
from employee where DEL_FLAG=1 order by payrollId

这里payrollId是employee表中的employee_id,admin_holiday是一个包含一个月国定假日信息的表

我的要求是,如果月份是当月,那么工作日应该是今天的日期。例如,当前月份是 2017 年 5 月,到今天(即 22/05/2017),除周末外的工作日数为 15(根据印度教日历,2017 年 5 月 10 日是国定假日。

如何获得所需的结果。

注意此操作必须在单个 select 语句中执行,并且不能在其他 pl/sql 块等中执行。

【问题讨论】:

    标签: oracle oracle11g


    【解决方案1】:

    这是我将如何处理等效查询。通过将日期范围计算放入一个小的交叉连接查询中,您可以在查询的其余部分轻松访问结果。

    SELECT
         e.payroll_id AS payrollId
      ,  cj. working_days
    FROM employee e
    cross join (
            select
                 GREATEST(NEXT_DAY(start_date, 'MON') - start_date - 2, 0) 
                + ((NEXT_DAY(end_date, 'MON') - NEXT_DAY(start_date, 'MON'))/7)*5
                - GREATEST(NEXT_DAY(end_date, 'MON') - end_date - 3, 0) 
                - (
                      SELECT COUNT(holiday) 
                      FROM admin_holiday
                      WHERE holiday_date BETWEEN start_date AND end_date
                   ) 
                  as working_days
            FROM (
                  select
                     to_date('20170501','yyyymmdd')  as start_date
                   , to_date('20170522','yyyymmdd')  as end_date
                  from dual
                )
            ) cj
    WHERE e.DEL_FLAG = 1
    ORDER BY e.payrollId
    

    工作日逻辑是:

    计算第一周的前导天数 +(计算周一/周五期间的数量)* 5 - 最后一周的尾随天数 - 表格中的额外假期:

    select
          GREATEST(NEXT_DAY(start_date, 'MON') - start_date - 2, 0) 
        + ((NEXT_DAY(end_date, 'MON') - NEXT_DAY(start_date, 'MON'))/7)*5
        - GREATEST(NEXT_DAY(end_date, 'MON') - end_date - 3, 0) 
        - (
              SELECT COUNT(holiday) 
              FROM admin_holiday
              WHERE holiday_date BETWEEN start_date AND end_date
           ) 
          as working_days
        , start_date
        , end_date
        , holidays
        , end_date - start_date
    FROM (
          select
             trunc(sysdate,'MM')  as start_date
           , trunc(sysdate)       as end_date
          from dual
        )
    

    示例(这里没有零假期):

    +--------------+--------------+-------------+------------+-------------------------+
    | WORKING_DAYS | START_DATE   | END_DATE    | HOLIDAYS   |   END_DATE-START_DATE   |
    +--------------+--------------+-------------+------------+-------------------------+
    |           16 |  01.05.2017  | 22.05.2017  |          0 |                      21 |
    +--------------+--------------+-------------+------------+-------------------------+
    

    要手动设置日期,您可以这样做:

    select
          GREATEST(NEXT_DAY(start_date, 'MON') - start_date - 2, 0) 
        + ((NEXT_DAY(end_date, 'MON') - NEXT_DAY(start_date, 'MON'))/7)*5
        - GREATEST(NEXT_DAY(end_date, 'MON') - end_date - 3, 0) 
        - (
              SELECT COUNT(holiday) 
              FROM admin_holiday
              WHERE holiday_date BETWEEN start_date AND end_date
           ) 
          as working_days
    FROM (
          select
             to_date('20170501','yyyymmdd')  as start_date
           , to_date('20170522','yyyymmdd')  as end_date
          from dual
        )
    

    【讨论】:

    • 我究竟应该在哪里对相应日期的查询进行更改,因为这给了我以下错误-- ORA-00923: FROM keyword not found where expected 00923. 00000 - "FROM keyword not found where预期的” 。我在 select 子句中将 start_date 替换为 2017 年 1 月 1 日,将 end_date 替换为 2017 年 5 月 31 日
    • 在以 "as start_date" 和 "as end_date" 结尾的行中;恐怕我不知道如何让它更明显。
    • 以防万一您需要了解我的逻辑如何应用于您的原始查询,我已经添加了我的答案的另一部分(在顶部)。我相信您会花时间做出回应(就像我为您所做的那样)。
    • 在某些情况下,我得到了适当的结果,而在其他情况下,我得到的结果比实际计数多出 +1。你能告诉我可能是什么原因吗?
    • 请您添加示例数据和预期结果
    猜你喜欢
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多