【问题标题】:Counting business days between two dates for each row in a table计算表中每一行的两个日期之间的工作日
【发布时间】:2018-04-03 18:22:12
【问题描述】:

我正在尝试实现this askTom solution 来计算表中两个日期字段之间的工作日。

 select count(*)
   from ( select rownum rnum
            from all_objects
           where rownum <= to_date('&1') - to_date('&2')+1 )
  where to_char( to_date('&2')+rnum-1, 'DY' ) not in ( 'SAT', 'SUN' )

我不知道如何将值传递给 toms 代码或如何解决,以便每次选择执行时使用不同的日期集并获得类似的输出:

rowid | bussiness_days

我想这可以通过 PL/SQL 块来实现,但如果可能的话,我更愿意将其保留为查询。是否可以使用上面选择的 &1 参数传递值?

【问题讨论】:

  • 你打算如何运行这个?这两个日期从何而来?
  • 我喜欢将它作为一个简单的查询运行,两个日期是表中的列。我想计算该表中某些行的工作日。

标签: sql oracle


【解决方案1】:

这与最初的 askTom 不同,但如果您使用的是 11gR2,则可以使用递归 CTE:

with rcte(a,b, i, is_wd) as (
select from_dt , to_dt , id, case when (to_char(from_dt, 'DY') in ('SAT','SUN')) then 0 else 1 end from t
  union all
  select decode(a, null, a,a+1), b, i, case when (to_char(a, 'DY') in ('SAT','SUN')) then 0 else 1 end 
  from rcte
  where a+1 <= b
)
select i id, sum(is_wd) 
from rcte
group by i

其中 t 是包含“from_dates”和“to_dates”的表

Here is a sqlfiddle demo

【讨论】:

    【解决方案2】:

    试试这个:

    SELECT COUNT(*)
       FROM ( SELECT ROWNUM rnum
                FROM all_objects
               WHERE ROWNUM <= TO_DATE('2014-02-07','yyyy-mm-dd') - TO_DATE('2014-02-01','yyyy-mm-dd')+1 )
      WHERE TO_CHAR( TO_DATE('2014-02-01','yyyy-mm-dd')+rnum-1, 'DY' ) NOT IN ( 'SAT', 'SUN' )
    

    但是,它至少有两个问题:

    • 假定会话NLS_DATE_LANGUAGE 设置为英文
    • 如果 ALL_OBJECTS 中的行数小于范围之间的天数,则查询会给出错误的结果。

    该版本不易出错且速度更快:

    WITH t AS   
        (SELECT TO_DATE('2014-02-01','yyyy-mm-dd')+LEVEL-1 the_date 
        FROM dual
        CONNECT BY TO_DATE('2014-02-01','yyyy-mm-dd')+LEVEL-1 <= TO_DATE('2014-02-07','yyyy-mm-dd'))
    SELECT COUNT(*)
    FROM t
    WHERE TO_CHAR(the_date, 'DY', 'NLS_DATE_LANGUAGE = AMERICAN') NOT IN ( 'SAT', 'SUN' )
    

    【讨论】:

      【解决方案3】:

      这是日历表派上用场的另一种情况。日历表的每个日期都有一行。

      如果周六和周日不是工作日,那么假期很可能也不是。日历表中用于指示节假日的字段可以更轻松地将它们从工作日计算中排除。

      【讨论】:

      • 我们的数据模型中已经有一个日历表,但它只记录银行假日,不包括周六和周日。
      • 如果你有日历表,为什么不用它来解决这个问题呢?
      猜你喜欢
      • 2010-09-20
      • 2018-08-03
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-13
      相关资源
      最近更新 更多