根据SQL中的开始/停止日期每月对数据进行日历化

时间:2018-01-11 01:39:45

标签: sql oracle

我有一张表(有几十万行),其中包含一个包含值和相关开始/停止日期的记录。例如:

Start Date; End Date; Value
2010-01-15; 2010-02-15; 100
2010-02-15; 2010-03-10; 50

使用SQL,我如何重新分配'价值'根据开始和结束日期在相关月份中均匀地将其变成这样的东西?:

Year; Month; Calendarized Value
2010; 01; 50
2010; 02; 75
2010; 03; 25

开始日期和结束日期之间的跨度可能代表几天或多个月。

1 个答案:

答案 0 :(得分:0)

此查询应提供您要查找的内容。它将在开始日期和结束日期之间平均分配数月,即使日期仅相隔几天也能正常工作。我不确定您的桌子上是否有主键或唯一ID。如果是这样,请使用它代替这部分:

    AND PRIOR start_date = start_date
    AND PRIOR end_date = end_date
    AND PRIOR value = value

我的假设是每个start_date + end_date +值都是唯一的。

SELECT
    y "Year", m "Month", SUM(distr_value) "Calendarized Value"
FROM (
    SELECT
        TO_CHAR(ADD_MONTHS(start_date, LEVEL-1), 'mm') m
      , TO_CHAR(ADD_MONTHS(start_date, LEVEL-1), 'yyyy') y
      , value / (MONTHS_BETWEEN(TRUNC(end_date, 'MON'), TRUNC(start_date, 'MON'))+1) distr_value
    FROM
        my_table
    CONNECT BY
        LEVEL <= MONTHS_BETWEEN(TRUNC(end_date, 'MON'), TRUNC(start_date, 'MON'))+1
        AND PRIOR start_date = start_date
        AND PRIOR end_date = end_date
        AND PRIOR value = value
        AND PRIOR sys_guid() IS NOT NULL
)
GROUP BY
    y, m
ORDER BY
    y, m;