查找一个月内的星期三(或其他工作日)数 - Oracle SQL

时间:2017-02-24 00:16:56

标签: oracle

我找到了这个查询,用于查找一个月中的星期日数。 我一直在修补它,但无法弄清楚如何改变它,比如说,例如,一个月内星期三的数量。你能告诉我怎么样吗?

    with 
months as (
        select add_months(trunc(sysdate,'YEAR'),level-13) month
        from dual
    connect by level <= 36
  )
select to_char(month,'YYYY') year,
       to_char(month,'Month') month,
       to_char(month,'Day') first_day,
      to_char(last_day(month),'Day DD') last_day,
      4+
      case 
        when to_char(last_day(month),'DD') - decode(to_char(month,'D'),1,0,8 -to_char(month,'D')) >= 29
          then 1
        else 0
      end nb_sunday
   from months

2 个答案:

答案 0 :(得分:2)

这是游戏:你给我一年(如2015)和一周中的一天,以三个字母的字符串形式(如'Wed')。我将返回一个表格,其中包含当年的每个月,并且每周的天数等于您每月的投入。

简单地在此处实施我对MT0答案的评论中的建议。因为“如何将参数传递给查询”(通过绑定变量等)而不是本线程中的焦点,所以我对年份和星期几(在CTE中)进行了硬编码。

with 
     inputs ( yr, day_of_week ) as (
       select 2015, 'Wed' from dual
     ),
     prep ( dec31 ) as (
       select to_date(to_char(yr - 1) || '-12-31', 'yyyy-mm-dd') from inputs
     )
select     to_char(add_months(dec31, level), 'Mon-yyyy')               as mth,
           ( next_day(add_months(dec31, level)    , day_of_week) -
             next_day(add_months(dec31, level - 1), day_of_week) ) / 7 as cnt
from       inputs cross join prep
connect by level <= 12;

MTH       CNT
-------- ----
Jan-2015    4
Feb-2015    4
Mar-2015    4
Apr-2015    5
May-2015    4
Jun-2015    4
Jul-2015    5
Aug-2015    4
Sep-2015    5
Oct-2015    4
Nov-2015    4
Dec-2015    5

12 rows selected.

答案 1 :(得分:1)

本月的最后一个星期三是:

TRUNC( NEXT_DAY( LAST_DAY( :month ) - INTERVAL '7' DAY, 'WEDNESDAY' ) )

本月的第一个星期三是:

NEXT_DAY( TRUNC( :month, 'MM' ) - INTERVAL '1' DAY, 'WEDNESDAY' )

减去给出它们之间的天数。除以7并加1,得到星期三的数量:

SELECT ( TRUNC( NEXT_DAY( LAST_DAY( :month ) - INTERVAL '7' DAY, 'WEDNESDAY' ) )
       - NEXT_DAY( TRUNC( :month, 'MM' ) - INTERVAL '1' DAY, 'WEDNESDAY' )
       ) / 7 + 1
       AS number_of_wednesdays
FROM   DUAL;

或者您可以使用@mathguy建议的月份的第一个星期三和下个月的差异

SELECT ( NEXT_DAY(
           ADD_MONTHS( TRUNC( :month, 'MM' ), 1 ) - INTERVAL '1' DAY,
           'WEDNESDAY'
         )
       - NEXT_DAY(
           TRUNC( :month, 'MM' ) - INTERVAL '1' DAY,
           'WEDNESDAY'
         )
       ) / 7
       AS number_of_wednesdays
FROM   DUAL;