【问题标题】:sql oracle ignore holidayssql oracle忽略节假日
【发布时间】:2015-04-16 09:29:08
【问题描述】:

我正在使用此代码来计算忽略周末的两个日期之间的差异:

SELECT To_date(SYSDATE) - 
      To_date('01.07.2014', 'DD.MM.YYYY') 
      - 2 * ( TRUNC(Next_day(To_date(SYSDATE) - 1, 'FRI')) 
      - TRUNC( Next_day(To_date('01.07.2014' , 'DD.MM.YYYY') 
      - 1, 'FRI')) ) / 7 AS DAYS_BETWEEN
FROM dual

我有另一个名为 table1 的表,其中存在“date”列(其类型为“DATE”),其中记录了所有假日日期。

示例表1:

DATES

12.06.2011
19.06.2014
09.05.2013
...

我正在尝试让我的代码检查此表,并且如果一个日期介于上述两个日期之间,则输出中的日期为 -1 天。

【问题讨论】:

    标签: sql oracle date oracle-sqldeveloper weekend


    【解决方案1】:

    如果你把它分成以下几个任务应该很容易:

    • 使用 Row Generator 方法生成两个给定日期之间的所有日期,如 here 所示。
    • 忽略周末的日期,即周六和周日
    • 检查范围内的日期是否与假期表中的任何匹配。

    以下行生成器查询将为您提供工作日总数,即包括星期六和星期日

    SQL> WITH dates AS
      2    (SELECT to_date('01/01/2014', 'DD/MM/YYYY') date1,
      3      to_date('31/12/2014', 'DD/MM/YYYY') date2
      4    FROM dual
      5    )
      6  SELECT SUM(weekday) weekday_count
      7  FROM
      8    (SELECT
      9      CASE
     10        WHEN TO_CHAR(date1+LEVEL-1, 'DY','NLS_DATE_LANGUAGE=AMERICAN')
     11             NOT IN ('SAT', 'SUN')
     12        THEN 1
     13        ELSE 0
     14      END weekday
     15    FROM dates
     16      CONNECT BY LEVEL <= date2-date1+1
     17    )
     18  /
    
    WEEKDAY_COUNT
    -------------
              261
    
    SQL>
    

    现在,基于上面的行生成器查询,让我们看一个测试用例。

    以下查询将计算 2014 年 1 月 1 日2014 年 12 月 31 日 之间的工作日数,不包括表中提到的节假日。

    WITH 子句仅用作表格,在您的情况下,您可以简单地使用您的假日表格

    SQL> WITH dates
      2       AS (SELECT To_date('01/01/2014', 'DD/MM/YYYY') date1,
      3                  To_date('31/12/2014', 'DD/MM/YYYY') date2
      4           FROM   dual),
      5       holidays
      6       AS (SELECT To_date('12.06.2011', 'DD.MM.YYYY') holiday FROM   dual UNION ALL
      7           SELECT To_date('19.06.2014', 'DD.MM.YYYY') holiday FROM   dual UNION ALL
      8           SELECT To_date('09.05.2013', 'DD.MM.YYYY') holiday FROM   dual),
      9       count_of_weekdays
     10       AS (SELECT SUM(weekday) weekday_count
     11           FROM   (SELECT CASE
     12                            WHEN To_char(date1 + LEVEL - 1, 'DY',
     13                                 'NLS_DATE_LANGUAGE=AMERICAN')
     14                                 NOT IN (
     15                                 'SAT',
     16                                 'SUN' ) THEN 1
     17                            ELSE 0
     18                          END weekday
     19                   FROM   dates
     20                   CONNECT BY LEVEL <= date2 - date1 + 1)),
     21       count_of_holidays
     22       AS (SELECT Count(*) holiday_count
     23           FROM   holidays
     24           WHERE  holiday NOT BETWEEN To_date('01/01/2015', 'DD/MM/YYYY') AND
     25                                      To_date('31/03/2015', 'DD/MM/YYYY'))
     26  SELECT weekday_count - holiday_count as working_day_count
     27  FROM   count_of_weekdays,
     28         count_of_holidays
     29  /
    
    WORKING_DAY_COUNT
    -----------------
                  258
    
    SQL>
    

    共有261个工作日,其中假期表中有3个假期。因此,输出中的工作日总数为261 - 3 = 258

    【讨论】:

      【解决方案2】:
      SELECT To_date(sysdate)- To_date('01.07.2014','DD.MM.YYYY')
      - (2 * (to_char(To_date(sysdate), 'WW') - to_char(To_date('01.07.2014','DD.MM.YYYY'), 'WW'))) AS DAYS_BETWEEN 
      FROM dual
      

      【讨论】:

      • 你好,马特——这不是和我上面的一样吗?
      • 好吧,我需要换个说法:我的代码给我 207 和你的 309 - 它不包括周末吗?
      • @piguy 现在试试,改了一些括号
      • 这里还是 309 作为输出
      • 我正在使用 Toad for oracle
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      相关资源
      最近更新 更多