You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据表中给定起止日期范围统计字段总和并按单日拆分输出

实现方案

核心思路是先生成查询参数ra_frdt到ra_todt范围内的所有连续自然日序列,再和你原有聚合得到的task时间区间做关联,匹配每个自然日所属的task区间即可完成拆分。
以下是不同数据库的实现代码:

Oracle 版本(你当前用的to_date语法符合Oracle规范,优先参考这个)

WITH date_range AS (
    -- 生成参数范围内的所有连续自然日
    SELECT to_date(:ra_frdt,'dd/mm/yyyy') + LEVEL - 1 AS dt
    FROM dual
    CONNECT BY LEVEL <= to_date(:ra_todt,'dd/mm/yyyy') - to_date(:ra_frdt,'dd/mm/yyyy') + 1
),
task_agg AS (
    -- 保留你原有的聚合逻辑
    SELECT sum(task_changepoint) task_changepoint, Task_id, task_dt_from, task_dt_to
    FROM fb_task 
    WHERE (task_dt_from BETWEEN to_date(:ra_frdt,'dd/mm/yyyy') AND to_date(:ra_todt,'dd/mm/yyyy')) 
        OR (task_dt_to BETWEEN to_date(:ra_frdt,'dd/mm/yyyy') AND to_date(:ra_todt,'dd/mm/yyyy'))
    GROUP BY Task_id, task_dt_from, task_dt_to
)
-- 关联得到单日维度的结果
SELECT 
    ta.task_changepoint,
    ta.Task_id,
    to_char(dr.dt, 'dd/mm/yyyy') AS date
FROM task_agg ta
JOIN date_range dr 
    ON dr.dt BETWEEN ta.task_dt_from AND ta.task_dt_to
ORDER BY ta.Task_id, dr.dt;

MySQL 8.0+ 版本

WITH RECURSIVE date_range AS (
    SELECT STR_TO_DATE(:ra_frdt,'%d/%m/%Y') AS dt
    UNION ALL
    SELECT dt + INTERVAL 1 DAY 
    FROM date_range
    WHERE dt < STR_TO_DATE(:ra_todt,'%d/%m/%Y')
),
task_agg AS (
    SELECT sum(task_changepoint) task_changepoint, Task_id, task_dt_from, task_dt_to
    FROM fb_task 
    WHERE (task_dt_from BETWEEN STR_TO_DATE(:ra_frdt,'%d/%m/%Y') AND STR_TO_DATE(:ra_todt,'%d/%m/%Y')) 
        OR (task_dt_to BETWEEN STR_TO_DATE(:ra_frdt,'%d/%m/%Y') AND STR_TO_DATE(:ra_todt,'%d/%m/%Y'))
    GROUP BY Task_id, task_dt_from, task_dt_to
)
SELECT 
    ta.task_changepoint,
    ta.Task_id,
    DATE_FORMAT(dr.dt, '%d/%m/%Y') AS date
FROM task_agg ta
JOIN date_range dr 
    ON dr.dt BETWEEN ta.task_dt_from AND ta.task_dt_to
ORDER BY ta.Task_id, dr.dt;

PostgreSQL 版本

WITH date_range AS (
    SELECT generate_series(
        to_date(:ra_frdt,'dd/mm/yyyy'),
        to_date(:ra_todt,'dd/mm/yyyy'),
        '1 day'::interval
    ) AS dt
),
task_agg AS (
    SELECT sum(task_changepoint) task_changepoint, Task_id, task_dt_from, task_dt_to
    FROM fb_task 
    WHERE (task_dt_from BETWEEN to_date(:ra_frdt,'dd/mm/yyyy') AND to_date(:ra_todt,'dd/mm/yyyy')) 
        OR (task_dt_to BETWEEN to_date(:ra_frdt,'dd/mm/yyyy') AND to_date(:ra_todt,'dd/mm/yyyy'))
    GROUP BY Task_id, task_dt_from, task_dt_to
)
SELECT 
    ta.task_changepoint,
    ta.Task_id,
    to_char(dr.dt, 'dd/mm/yyyy') AS date
FROM task_agg ta
JOIN date_range dr 
    ON dr.dt BETWEEN ta.task_dt_from AND ta.task_dt_to
ORDER BY ta.Task_id, dr.dt;

注意事项

如果你的数据中存在同一个Task_id的多个时间区间重叠的情况,同一个日期会匹配到多条记录,需要合并的话可以在外层再增加一层按Task_id、dt分组的聚合逻辑即可。

内容的提问来源于stack exchange,提问作者XXAXX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:30:04