【问题标题】:use to_date oracle function using week number and day number oracle使用 to_date oracle 函数使用星期数和天数 oracle
【发布时间】:2016-01-07 16:58:32
【问题描述】:

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

例如,我有一个名为 Club 的表,它存储了可以参加考试的日期和星期几,它具有 dayOfExamweekOfExam 属性。

dayOfExam=2 (Monday).   
weekOfExam=1

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

我试过用like

TO_DATE('21012016','DWMMYYYY');

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

【问题讨论】:

    标签: plsql oracle10g oracle-sqldeveloper


    【解决方案1】:

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

    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;
    

    【讨论】:

    • 谢谢!那行得通...但是我不想在add_months中给出日期'2016-01-01',而是想分配任何日期..例如,如果考试只编程到11月并且我想在12月安排一个新的考试,我想要检查最后一次考试日期(在本例中为“07-NOV-16”)并从该日期开始,创建 12 月日期(无论如何从一开始就将是 05-dic-16,但我不能总是使用第一天本月)
    • @GonzaloMachado - 我不确定我是否理解你的问题。您显然可以更改first_of_month CTE 中的查询。如果你想做select add_months( trunc(date '2016-11-07', 'MM'), 1 ) mnth from dual,你会得到下个月的日期。
    • 问题是它不适用于每一天/周数......如果我使用第 2 天(星期一)和第 4 周它返回错误的日期,还有 7 天......我认为这是针对 +7 的,但不是针对每个案例....我上面试图解释的是我有 2 个案例...如果没有任何预定的考试,我可以使用该代码,并计算从每个月的第一天开始的第二天......但如果它存在之前的考试(在 11 月第一周的第二天) 07-nov-16 我需要从中计算下一个日期及其 05-dic- 16
    【解决方案2】:

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

    如果您想在一个月内第 n 次出现给定的工作日,您可以使用以下代码:

    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 周的给定星期几中的日期,代码如下:

    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;
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-01
      • 2012-07-28
      • 2011-10-28
      相关资源
      最近更新 更多