【问题标题】:querying how many weeks between a date range and showing them their dates查询日期范围之间的周数并显示他们的日期
【发布时间】:2015-02-05 19:49:16
【问题描述】:

我需要计算周数,并在表格中列出它们各自的日期范围。

所以我现在拥有的是

select countinous_weeks, decode(countinous_weeks-52,0,trunc(countinous_weeks),trunc(countinous_weeks)+1)
from (
select (TO_DATE('01-01-1995', 'DD/MM/YYYY') - TO_DATE('01-01-1994','DD/MM/YYYY'))/7 countinous_weeks
from dual) wks

它只显示该范围内的周数。我的目标是在 53 行中显示它们并显示每周的日期范围。所以让我们说第一周

WEEK RANGE
1    01-01-1994 Until 07-01-1994 ... etc

请帮我解决这个问题.. 非常感谢

【问题讨论】:

    标签: sql oracle date


    【解决方案1】:

    这很有趣。它涉及以下内容 -

    1. 日期行生成器
    2. 周数
    3. ROW_NUMBER() 为每一周的日期分配排名
    4. 最后 LISTAGG 聚合从第 3 步获取的行

    让我们看看它的工作原理 -

    SQL> WITH DATA AS
      2    (SELECT to_date('01/01/1994', 'DD/MM/YYYY') date1,
      3      to_date('31/12/1994', 'DD/MM/YYYY') date2
      4    FROM dual
      5    )
      6  SELECT the_week,
      7    listagg(the_date, ' until ') within GROUP (
      8  ORDER BY to_date(the_date, 'DD/MM/YYYY')) the_date_range
      9  FROM
     10    (SELECT the_week,
     11      the_date,
     12      row_number() over(partition BY the_week order by the_week, to_date(the_date, 'DD/MM/YYYY')) rn
     13    FROM
     14      (SELECT TO_CHAR(date1+level-1, 'WW') the_week ,
     15        TO_CHAR(date1      +level-1, 'DD/MM/YYYY') the_date
     16      FROM data
     17        CONNECT BY LEVEL <= date2-date1+1
     18      )
     19    )
     20  WHERE rn in( 1, 7)
     21  GROUP BY the_week
     22  /
    
    TH THE_DATE_RANGE
    -- ---------------------------------------------
    01 01/01/1994 until 07/01/1994
    02 08/01/1994 until 14/01/1994
    03 15/01/1994 until 21/01/1994
    04 22/01/1994 until 28/01/1994
    05 29/01/1994 until 04/02/1994
    06 05/02/1994 until 11/02/1994
    07 12/02/1994 until 18/02/1994
    08 19/02/1994 until 25/02/1994
    09 26/02/1994 until 04/03/1994
    10 05/03/1994 until 11/03/1994
    11 12/03/1994 until 18/03/1994
    12 19/03/1994 until 25/03/1994
    13 26/03/1994 until 01/04/1994
    14 02/04/1994 until 08/04/1994
    15 09/04/1994 until 15/04/1994
    16 16/04/1994 until 22/04/1994
    17 23/04/1994 until 29/04/1994
    18 30/04/1994 until 06/05/1994
    19 07/05/1994 until 13/05/1994
    20 14/05/1994 until 20/05/1994
    21 21/05/1994 until 27/05/1994
    22 28/05/1994 until 03/06/1994
    23 04/06/1994 until 10/06/1994
    24 11/06/1994 until 17/06/1994
    25 18/06/1994 until 24/06/1994
    26 25/06/1994 until 01/07/1994
    27 02/07/1994 until 08/07/1994
    28 09/07/1994 until 15/07/1994
    29 16/07/1994 until 22/07/1994
    30 23/07/1994 until 29/07/1994
    31 30/07/1994 until 05/08/1994
    32 06/08/1994 until 12/08/1994
    33 13/08/1994 until 19/08/1994
    34 20/08/1994 until 26/08/1994
    35 27/08/1994 until 02/09/1994
    36 03/09/1994 until 09/09/1994
    37 10/09/1994 until 16/09/1994
    38 17/09/1994 until 23/09/1994
    39 24/09/1994 until 30/09/1994
    40 01/10/1994 until 07/10/1994
    41 08/10/1994 until 14/10/1994
    42 15/10/1994 until 21/10/1994
    43 22/10/1994 until 28/10/1994
    44 29/10/1994 until 04/11/1994
    45 05/11/1994 until 11/11/1994
    46 12/11/1994 until 18/11/1994
    47 19/11/1994 until 25/11/1994
    48 26/11/1994 until 02/12/1994
    49 03/12/1994 until 09/12/1994
    50 10/12/1994 until 16/12/1994
    51 17/12/1994 until 23/12/1994
    52 24/12/1994 until 30/12/1994
    53 31/12/1994
    
    53 rows selected.
    
    SQL>
    

    【讨论】:

    • 但我仍然有一个错误 lalit ORA-00923: FROM keyword not found where expected
    • 谢谢。检查是否有任何复制粘贴错误。或者,编辑您的问题并显示您的 sqlplus 会话。
    • 我确实检查过,但没有复制粘贴错误。我逐个字符地检查了
    • 您的脚本有一个错误:您为什么要按 TO_DATE(DD/MM/YYYY) 排序?这将在 1994 年 1 月 29 日之前对 04-FEB-1994 进行排序。而且您在第 5 行中看到日期的顺序错误!
    • @LalitKumarB 您也可以将 the_date 保留为实际的日期类型(而不是将其转换为转换) - 因为现在您从日期开始,将其转换为 char 并将其转换回用于分区和排序......
    【解决方案2】:

    这是查询。

    SELECT LEVEL , to_char( TO_DATE('01-01-1995', 'DD/MM/YYYY') + ( level * 7 ) - 7)  || ' until ' ||  to_char( TO_DATE('01-01-1995', 'DD/MM/YYYY') + ( level * 7 ) - 1 ) as range
      FROM DUAL
    CONNECT BY LEVEL <= ( select (TO_DATE('01-01-1995', 'DD/MM/YYYY') - TO_DATE('01-01-1994','DD/MM/YYYY'))/7 countinous_weeks
    from dual )
    

    【讨论】:

    • 不错的解决方案,但我想我必须为此打击你:TO_DATE('01-01-1995', 'DD/MM/YYYY') 如果您提供日期格式,请使用您实际提供的格式!!! -> DD-MM-YYYY
    • 这是一个不完整的解决方案。级别和周数不能视为与所需输出相同。最后一周总会被错过。
    【解决方案3】:

    好的 - 这是另一个我觉得更容易阅读的解决方案:

    SELECT LEVEL  running_number
          ,TO_CHAR( start_date + ( LEVEL - 1 ) * 7, 'WW' ) iso_date_week_number
          ,TO_CHAR( start_date + ( LEVEL - 1 ) * 7, 'DD-MM-YYYY' )
        || ' until '
        || TO_CHAR( start_date + ( LEVEL ) * 7, 'DD-MM-YYYY' )
      FROM
      ( SELECT TO_DATE('01-01-1994', 'DD-MM-YYYY') start_date
              ,TO_DATE('01-01-1995', 'DD-MM-YYYY') end_date
          FROM DUAL
      )
    CONNECT BY start_date + ( LEVEL - 1 ) * 7 < end_date;
    

    我使用 connect by 并为每个级别添加 7 天,直到我到达结束日期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-06
      • 1970-01-01
      • 2014-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多