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

不依赖RowId序列的SQLite累计求和问题咨询

解决SQLite中按时间顺序计算累计求和的问题

从你的描述来看,核心问题是原来的递归CTE依赖id(也就是RowId)的递增顺序计算累计和,但插入历史月份的记录时,新记录的id会比现有记录大,导致它被排在遍历顺序的最后,破坏了按year、month排序的累计逻辑。下面给你两种解决方案,优先推荐更简洁高效的窗口函数方案:

方案一:使用窗口函数(SQLite 3.25+ 推荐)

SQLite从3.25版本开始支持窗口函数,这和你在SQL Server中用SUM() OVER()的逻辑几乎一致,完全不需要递归,直接按year和month的顺序计算累计和:

SELECT 
    id, 
    month, 
    year, 
    value,
    -- 按year、month、id排序,保证累计顺序稳定
    SUM(value) OVER (ORDER BY year, month, id) AS rt
FROM Test
ORDER BY year, month, id;

这里额外加入id作为排序条件,是为了处理同年同月有多条记录的情况,避免累计顺序出现混乱。不管你什么时候插入哪个月份的记录,只要year和month值正确,累计和都会自动按时间顺序计算,完全不受id大小的影响。

方案二:调整递归CTE逻辑(兼容旧版本SQLite)

如果你使用的是不支持窗口函数的旧版SQLite,可以修改递归CTE的遍历逻辑,不再依赖id的大小,而是按year和month的时间顺序来遍历记录:

WITH RECURSIVE running AS (
    -- 起始点:取时间最早的那条记录(按year、month、id排序)
    SELECT 
        id, 
        month, 
        year, 
        value, 
        value AS rt
    FROM Test
    ORDER BY year, month, id
    LIMIT 1

    UNION ALL

    -- 递归部分:找到当前记录之后时间最早的下一条记录
    SELECT 
        t.id, 
        t.month, 
        t.year, 
        t.value, 
        t.value + r.rt AS rt
    FROM running r
    JOIN Test t ON 
        -- 匹配时间晚于当前记录的条件
        (t.year > r.year) 
        OR (t.year = r.year AND t.month > r.month)
        OR (t.year = r.year AND t.month = r.month AND t.id > r.id)
    WHERE NOT EXISTS (
        -- 确保中间没有更早的记录,保证取到的是真正的下一条
        SELECT 1 FROM Test t2
        WHERE 
            (t2.year > r.year AND t2.year < t.year)
            OR (t2.year = r.year AND t2.month > r.month AND t2.month < t.month)
            OR (t2.year = r.year AND t2.month = r.month AND t2.id > r.id AND t2.id < t.id)
    )
)
SELECT * FROM running
ORDER BY year, month, id;

这个递归CTE的逻辑是:每次找到当前记录之后时间最早的那条记录,而不是id最大的那条。这样即使插入了历史月份的记录(id很大但时间更早),遍历顺序也会按year、month自动调整,累计和自然就正确了。

补充说明

从SQL Server转过来的话,窗口函数应该是最符合你使用习惯的方案,它不仅代码简洁,执行效率也比递归CTE高很多。如果你的SQLite版本允许,一定要优先选择这个方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:35:28