根据范围内的月份开始日期分为多行输出

问题描述 投票:0回答:1

我有一个数据,其中给定两个日期,它使用以下查询创建一个间隔为 7 天的开始日期和结束日期范围。

WITH Ranges AS (
    SELECT
        TO_DATE('2023-10-16 00:00:00', 'YYYY-MM-DD HH24:MI:SS') START_DATE,
        TO_DATE('2023-11-13 00:00:00', 'YYYY-MM-DD HH24:MI:SS')   END_DATE
    FROM
        DUAL
)
SELECT
        GREATEST(START_DATE, TRUNC(START_DATE + 7 *(LEVEL - 1)))  WEEK_FIRST_DATE,
        LEAST(END_DATE, TRUNC(START_DATE + 7 *(LEVEL - 1)) + 7 - INTERVAL '1' SECOND) WEEK_LAST_DATE,
        LEVEL SL_NO
    FROM
        Ranges
    CONNECT BY
        START_DATE + 7 * ( LEVEL - 1 ) <= END_DATE

查询输出:

现在的要求是,如果该月的结束日期落在该范围内,则进一步划分并创建范围,然后从下一个日期开始计算接下来的 7 天,依此类推。 所以理想情况下,下面应该是输出

16-OCT-23 00:00:00  22-OCT-23 23:59:59  1
23-OCT-23 00:00:00  29-OCT-23 23:59:59  2
30-OCT-23 00:00:00  31-OCT-23 23:59:59 3 ---- as month end date falling in the range, so last date changed.
01-NOV-23 00:00:00 07-NOV-23 23:59:59   4 --- Calculate 7 days gap from next date onwards till we reach end date in the query
08-NOV-23 00:00:00  13-NOV-23 23:59:59  5
sql oracle common-table-expression date-range
1个回答
0
投票

修改您的查询以包含检查每个范围内月底的逻辑,并相应地创建其他范围。以下是您的查询的更新版本:

WITH Ranges AS (
    SELECT
        TO_DATE('2023-10-16 00:00:00', 'YYYY-MM-DD HH24:MI:SS') START_DATE,
        TO_DATE('2023-11-13 00:00:00', 'YYYY-MM-DD HH24:MI:SS') END_DATE
    FROM
        DUAL
)
SELECT
    GREATEST(START_DATE, TRUNC(START_DATE + 7 * (LEVEL - 1))) WEEK_FIRST_DATE,
    LEAST(END_DATE, TRUNC(START_DATE + 7 * (LEVEL - 1)) + 7 - INTERVAL '1' SECOND) WEEK_LAST_DATE,
    LEVEL SL_NO
FROM
    Ranges
CONNECT BY
    START_DATE + 7 * (LEVEL - 1) <= END_DATE
    AND PRIOR SYS_GUID() IS NOT NULL
START WITH
    START_DATE = PRIOR START_DATE
    AND LEVEL = 1
UNION ALL
SELECT
    GREATEST(TRUNC(ADD_MONTHS(WEEK_LAST_DATE, 1)), TRUNC(WEEK_LAST_DATE + INTERVAL '1' DAY)) WEEK_FIRST_DATE,
    LEAST(END_DATE, TRUNC(WEEK_LAST_DATE + INTERVAL '1' DAY) + 7 - INTERVAL '1' SECOND) WEEK_LAST_DATE,
    LEVEL + (SELECT MAX(LEVEL) FROM Ranges) SL_NO
FROM
    Ranges
CONNECT BY
    TRUNC(WEEK_LAST_DATE + INTERVAL '1' DAY) + 7 * (LEVEL - 1) <= END_DATE
    AND PRIOR SYS_GUID() IS NOT NULL
    AND PRIOR WEEK_LAST_DATE = WEEK_LAST_DATE
START WITH
    START_DATE = PRIOR START_DATE
    AND LEVEL = 1;

直接检查并给我反馈

© www.soinside.com 2019 - 2024. All rights reserved.