使用 to_date oracle 函数使用周数和天数 oracle

use to_date oracle function using week number and day number oracle

我正在尝试从星期几和月份的星期数中获取日期。

例如,我有一个名为 Club 的 table,用于存储哪一天和哪一周可以参加考试,它具有 dayOfExamweekOfExam 属性。

dayOfExam=2 (Monday).   
weekOfExam=1

这意味着每个月第一周的每个星期一都有考试。我需要 04-JAN-2016 ... 08-FEB-2016 .. 07-MAR-16 and so on....

我试过用 like

TO_DATE('21012016','DWMMYYYY');

有可能得到那个日期吗?谢谢。

也许有更简单的方法来做到这一点,但我写了两个选项。

如果您想要在一个月中的给定工作日出现 n-th 次,您可以使用此代码:

declare
    l_month_year char(6):= '012016'; -- JAN-2016
    l_date date;
begin
    with base as (
        select to_date(ltrim(to_char(level, '00'))||l_month_year, 'ddmmyyyy') examdate,
            to_char(to_date(ltrim(to_char(level, '00'))||l_month_year, 'ddmmyyyy'), 'd') dayofweek,
            count(*) over(partition by to_char(to_date(ltrim(to_char(level, '00'))||l_month_year, 'ddmmyyyy'), 'd') order by level rows between unbounded preceding and current row) ocurrence
        from dual
        connect by level <= to_number(to_char(last_day(to_date(l_month_year, 'mmyyyy')), 'dd'))
    )    
    select examdate
      into l_date 
      from base
     where ocurrence = 1 and dayofweek = 2;

    Dbms_Output.put_line(to_char(l_date, 'dd-MON-yyyy'));  
end;

如果您想要日期在每月 n-th 周的给定工作日中,那是代码:

declare
    l_month_year char(6):= '012016'; -- JAN-2016
    l_date date;
begin
    with base as (
        select to_date(ltrim(to_char(level, '00'))||l_month_year, 'ddmmyyyy') examdate,
            to_char(to_date(ltrim(to_char(level, '00'))||l_month_year, 'ddmmyyyy'), 'd') dayofweek,
            to_char(to_date(ltrim(to_char(level, '00'))||l_month_year, 'ddmmyyyy'), 'ww') - min(to_char(to_date(ltrim(to_char(level, '00'))||l_month_year, 'ddmmyyyy'), 'ww')) over() + 1 weekofmonth 
        from dual
        connect by level <= to_number(to_char(last_day(to_date(l_month_year, 'mmyyyy')), 'dd'))
    )    
    select examdate
      into l_date 
      from base
     where weekofmonth = 1 and dayofweek = 2;

    Dbms_Output.put_line(to_char(l_date, 'dd-MON-yyyy'));  
exception when no_data_found then
    Dbms_Output.put_line('there is not a day 2 in week 1 of '||to_char(to_date(l_month_year, 'mmyyyy'), 'Month-YYYY'));
end;

请注意,对于 February-2016,第一种情况会输出“01-FEV-2016”,因为它是第一周的星期一。第二种方式,输出为“08-FEV-2016”:二月的第2个星期一。

在 SQL 中,您可以只使用 next_day 并添加 7 天的倍数。如果你想 return 一年中每个月的日期,你可以这样做。如果您想要更多月数,您可以调整开始日期和前进的月数。

with x as (
  select 2 dayOfExam, 1 weekOfExam from dual
),
first_of_month as (
  select add_months( date '2016-01-01', level-1 ) mnth,
         dayOfExam,
         weekOfExam
    from x
 connect by level <= 12
)
select next_day( mnth, dayOfExam ) + 7 * (weekOfExam - 1) the_date
  from first_of_month;