获取当前月份的当前天数(节假日除外)

时间:2018-12-05 07:44:04

标签: sql oracle oracle11g

我是SQL的初学者。我必须从当前系统月份获取当前天数(天数),而不应该考虑周末(周六和周日)。

例如,如果我今天(05-Dec-2018)执行查询,则我的输出应为3(当前日期是05-12-2018,这里12月1日是星期六,2nd 12是星期日。希望在计算中包括周末。因此,星期一(12月3日)将为1,星期二(12月4日)将为2,星期三(12月5日)将为3。

任何对此高度赞赏的帮助。

4 个答案:

答案 0 :(得分:2)

您不需要使用分层查询,并且可以独立于NLS设置使用TRUNC( date_value, 'IW' )进行查询,以查找ISO星期的开始,始终是星期一。

所以:

TRUNC( SYSDATE, 'IW' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' )

将找到包含每月第一天的ISO周开始到当前ISO周开始之间的天数。将其乘以5/7将得出工作日数。

然后,您需要查找的是上个月发生了多少天并将其减去。可以使用以下方法找到它:

LEAST( TRUNC( SYSDATE, 'MM' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ), 5 )

,本周需要增加多少天;通过以下方式给出:

LEAST( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) + 1, 5 )

因此总数可以使用:

SELECT ( TRUNC( SYSDATE, 'IW' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ) ) * 5 / 7
       + LEAST( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) + 1, 5 )
       - LEAST( TRUNC( SYSDATE, 'MM' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ), 5 )
         AS Num_Week_Days
FROM  DUAL;

多天的示例:

WITH calendar ( date_value ) AS (
  SELECT DATE '2018-12-01' + LEVEL - 1
  FROM   DUAL
  CONNECT BY LEVEL <= 15
)
SELECT date_value,
       TO_CHAR( date_value, 'DY' ) AS day,
       ( TRUNC( date_value, 'IW' ) - TRUNC( TRUNC( date_value, 'MM' ), 'IW' ) ) * 5 / 7
       + LEAST( TRUNC( date_value ) - TRUNC( date_value, 'IW' ) + 1, 5 )
       - LEAST( TRUNC( date_value, 'MM' ) - TRUNC( TRUNC( date_value, 'MM' ), 'IW' ), 5 )
         AS Num_Week_Days
FROM  Calendar;

输出

DATE_VALUE  DAY NUM_WEEK_DAYS
----------  --- -------------
2018-12-01  SAT 0
2018-12-02  SUN 0
2018-12-03  MON 1
2018-12-04  TUE 2
2018-12-05  WED 3
2018-12-06  THU 4
2018-12-07  FRI 5
2018-12-08  SAT 5
2018-12-09  SUN 5
2018-12-10  MON 6
2018-12-11  TUE 7
2018-12-12  WED 8
2018-12-13  THU 9
2018-12-14  FRI 10
2018-12-15  SAT 10

答案 1 :(得分:1)

如果您在数据库中维护一个calendar表,则这种类型的查询非常容易编写。这是一个查询,该查询生成从月初到今天(包括今天)的全天的部分日历。然后,我们可以计算工作日的数量。

select count(*)
  from (select trunc(sysdate, 'MM') - 1 + level as d
          from dual 
       connect by level <= trunc(sysdate, 'DD') + 1 -- Today
                         - trunc(sysdate, 'MM')     -- First day of current month
       )
 -- Exclude weekends 
 where to_char(d, 'DY', 'nls_date_language=american') not in('SAT', 'SUN') 
 ;

答案 2 :(得分:1)

您可以将此SQL select语句与connect by level子句一起使用:

 select sum(dy) "Total Day"
   from
   (
    select (case when to_char(sysdate-level+1,'D','nls_date_language=turkish') in (6,7)
                 then 0
                 else 1 end ) as dy
      from dual
   connect by level <= to_number(to_char(sysdate,'DD'))
   );

  Total Day
  ---------
      3

您可以尝试其他情况,方法是将两个sysdate关键字都替换为sysdate + 3sysdate + 4sysdate + 5 ...等。

答案 3 :(得分:-2)

这应该适用于SQL Server

SET @today= '2018-12-14'

SET @firstDate = (SELECT DATEADD(month, DATEDIFF(month, 0, @today), 0) AS StartOfMonth);

WITH allDates AS 
(
    SELECT 
            @firstDate AS DT
    UNION ALL
            SELECT 
                DATEADD(dd, 1, DT)
            FROM 
                allDates as S 
            WHERE 
                DATEADD(dd, 1, DT) <= @today
)
SELECT  count(*)  FROM allDates  where  DATENAME(dw,DT) <> 'Saturday' and DATENAME(dw,DT) <> 'Sunday' option (maxrecursion 0)