【问题标题】:Oracle Week Number From Date ISO Week But From December 1从日期 ISO 周开始但从 12 月 1 日开始的 Oracle 周数
【发布时间】:2016-11-02 18:13:00
【问题描述】:

好的,我有一个运行良好的查询,它计算从 12 月 1 日(我们的销售会计年度开始)开始的周数。

现在要求发生了变化。我仍然需要根据字段 (Invoice_Date) 计算周数。但是,现在我需要从最近的星期一开始计数,而不是从 12 月 1 日(12 月 1 日至 7 日,第 1 周等)开始计数。据我了解,ISO 周是我正在寻找的,但它从 1 月 1 日开始。如何修改它以从 12 月 1 日开始工作?

任何帮助将不胜感激。

【问题讨论】:

  • 最近的星期一可以在 12 月 1 日之前,之后,还是两者之一?显示您期望的一些日期和周数可能会有所帮助。
  • 是的,最近的星期一可能在 12 月 1 日之前。我正在尝试比较一年中相同数量的“发票日期”。我需要财政周总是反映周一至周日。 2015 财年第 1 周为 12 月 1 日至 7 日,但 2016 财年第 1 周为 11 月 30 日至 12 月 6 日。我的数据有每笔交易的发票日期。我想在我的查询中计算“FW”(财政周),所以如果我做一个比较今年年初至今第 50 周和去年年初至今第 50 周的报告,我总是处理相同数量的星期一,相同数量的星期二等等。我说得有道理吗?

标签: oracle date


【解决方案1】:

select next_day(to_date('0112' || to_char(sysdate, 'YYYY'),'ddmmyyyy') - 1, 'MONDAY') dec_mon from dual;
给你当年 12 月的第一个星期一

周数就是ceil((sysdate - dec_mon)/7)

如果您想在 12 月 1 日之前的上周一获得,可以通过:

select next_day(to_date('2511' || to_char(sysdate, 'YYYY'),'ddmmyyyy') - 1, 'MONDAY') 
from dual;

【讨论】:

    【解决方案2】:

    在这个提议的解决方案中,我首先构建一个“帮助表”,显示每个会计年度的 Monday_fromMonday_to(在第三个 CTE 中,名为 ranges)。然后我建立了一些测试日期——我很懒,我应该使用to_date(),所以我也可以包含时间组件。实际解决方案中的连接条件(在代码末尾)是这样编写的,因此对于具有非零“时间”组件的日期,它无需修改即可工作。

    我使用了 Oracle 11.2 的好特性,它允许我们在 CTE 的声明中提供列别名 - 否则列别名需要移动到各自的 SELECTs 中。否则,该解决方案至少应该适用于 Oracle 9 及更高版本(我认为)。

    with
         y ( dt ) as (
           select add_months(date '2000-12-01', 12 * level )
           from   dual
           connect by level <= 30
         ),
         m ( dt ) as (
           select trunc(dt, 'iw') + case when dt - trunc(dt, 'iw') <= 3 then 0 else 7 end
           from   y       
         ),
         ranges ( monday_from, monday_to ) as (
           select dt, lead(dt) over (order by dt) - 1
           from   m
         ),
         test_dates ( t_date ) as (
           select date '2013-02-23' from dual union all
           select date '2008-12-01' from dual union all
           select date '2008-04-28' from dual union all
           select date '2016-11-29' from dual
         )
    select t_date, monday_from, 1 + trunc((t_date - monday_from)/7) as week_no
    from   test_dates t inner join ranges r
           on t.t_date >= r.monday_from and t.t_date < r.monday_to
    ;
    
    T_DATE              MONDAY_FROM            WEEK_NO
    ------------------- ------------------- ----------
    2008-04-28 00:00:00 2007-12-03 00:00:00         22
    2008-12-01 00:00:00 2008-12-01 00:00:00          1
    2013-02-23 00:00:00 2012-12-03 00:00:00         12
    2016-11-29 00:00:00 2016-11-28 00:00:00          1
    

    【讨论】:

      【解决方案3】:

      使用以下函数返回距任何给定日期最近的星期一:

      NEXT_DAY(some_date-4,'Monday')
      

      如该查询所示:

      with dts(some_date) as (
        select date '2006-12-1' from dual
        union all
        select add_months(some_date,12)
          from dts
         where some_date <= date '2014-12-1'
      )
      select some_date
           , next_day(some_date-4,'monday') nearest
           , some_date - next_day(some_date-4,'monday') dist
        from dts;
      
      SOME_DATE   NEAREST           DIST
      ----------- ----------- ----------
      01-DEC-2006 04-DEC-2006         -3
      01-DEC-2007 03-DEC-2007         -2
      01-DEC-2008 01-DEC-2008          0
      01-DEC-2009 30-NOV-2009          1
      01-DEC-2010 29-NOV-2010          2
      01-DEC-2011 28-NOV-2011          3
      01-DEC-2012 03-DEC-2012         -2
      01-DEC-2013 02-DEC-2013         -1
      01-DEC-2014 01-DEC-2014          0
      01-DEC-2015 30-NOV-2015          1
      
       10 rows selected 
      

      【讨论】:

        猜你喜欢
        • 2022-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-19
        • 1970-01-01
        • 2019-08-29
        相关资源
        最近更新 更多