3

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

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 的表,其中存在“日期”列(其类型为“日期”),其中记录了假期的所有日期。

示例表 1:

DATES

12.06.2011
19.06.2014
09.05.2013
...

我试图让我的代码检查这个表,如果一个日期在上面的两个日期之间,它会在输出中产生 -1 天。

4

2 回答 2

2

如果将其分为以下任务,应该很容易:

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

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

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子句仅将其用作表,在您的情况下,您可以简单地使用您的holiday table

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

于 2015-04-16T09:59:08.033 回答
0
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
于 2015-04-16T09:37:29.680 回答