使用 to_date oracle 函数使用星期数和天数 oracle

Posted

技术标签:

【中文标题】使用 to_date oracle 函数使用星期数和天数 oracle【英文标题】:use to_date oracle function using week number and day number 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');

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

【问题讨论】:

【参考方案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”:二月第二次出现的星期一。

【讨论】:

以上是关于使用 to_date oracle 函数使用星期数和天数 oracle的主要内容,如果未能解决你的问题,请参考以下文章

oracle如何根据传入的时间参数,得到这个参数所在周的周一至周五的日期和星期数

oracle中to_date详细用法示例(oracle日期格式转换)

oracle的查询语句中to_date()是啥意思,那里面的参数分别代表啥含义?

ORACLE中to_char、to_date、trunc、to_number、cast函数

oracle中的to_date函数

SQL 日期函数问题;我想写一个查询语句,是查表中日期字段后十天的数据