ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SQLazy:分组累计求和

2026/9/3 16:37:39 拓冰建站 浏览量
SQLazy:分组累计求和 问题描述只保留开票行金额累计从上次开票开始有一张业务流水表包含 ID、Date、Invoiced 和 Amount 四个字段。每个月有一条记录其中 Invoiced1 表示该月开了发票。现在要输出每个 ID 下所有开票月份并且每张发票的金额等于自上个月开票或开始到当前月所有金额的总和包括当前发票本身。源数据IDDateInvoicedAmountAAA2023-01010AAA2023-02015AAA2023-03115AAA2023-04010AAA2023-05010AAA2023-06110BBB2022-05040BBB2022-06120BBB2022-07030BBB2022-08130期望结果只保留开票行每行 Amount 是自上次开票以来的累计值。IDDateInvoicedAmountAAA2023-03140AAA2023-06130BBB2022-06160BBB2022-08160以 AAA 为例第一张发票 2023-03之前有 1 月 (10) 2 月 (15) 自身 (15) 40第二张发票 2023-06上次发票之后有 4 月 (10) 5 月 (10) 自身 (10) 30BBB 同理。SQLazy 分步实现ValueAnchorStatementt1invoicesort id,dt desct2compute invoiced cum as grp partition idt3summarize dt max as dt invoiced max as invoiced amount sum as amount group id grpt4derive id dt invoiced amount下面分别解释一下这些步骤。第 1 步按 ID 和日期排序日期降序sort id,dt desc这一步是为了后续分组做准备。降序排列后一个发票行与它前面的非开票行会先被处理累计求和时这些行会被归入同一组。第 2 步对 invoiced 做累计求和生成分组号compute invoiced cum as grp partition id在每个 ID 分区内按当前顺序降序对 invoiced 进行累计求和包括当前行。结果如下第 3 步按 ID 和 grp 分组汇总summarize dt max as dt invoiced max as invoiced amount sum as amount group id grpdt max因为降序每组内日期最大的是开票月份发票行的日期。invoiced max每组至少有一个 invoiced1所以最大值是 1。amount sum累加该组所有金额即自该发票以来包括自身的总和。第 4 步选择需要的列derive id dt invoiced amount这一步只是清理输出去掉辅助列 grp。编译生成 SQL完成上述步骤后通过 SQLazy 的编译器可以生成等价的原生 SQL无需手动编写。这里生成 MySQL 语句WITH t3 AS ( SELECT id, grp, MAX(dt) AS dt, MAX(invoiced) AS invoiced, SUM(amount) AS amount FROM ( SELECT id, dt, invoiced, amount, SUM(invoiced) OVER ( PARTITION BY id ORDER BY CASE WHEN id IS NULL THEN 1 ELSE 0 END, id ASC, CASE WHEN dt IS NULL THEN 1 ELSE 0 END, dt DESC ROWS UNBOUNDED PRECEDING ) AS grp FROM invoice ) t2 GROUP BY id, grp ) SELECT id, dt, invoiced, amount FROM t3 ORDER BY id, grp你不需要读懂或调试这段 SQL只需确认前面四步的逻辑正确编译器就会输出可运行的代码。列个表格总结一下传统 SQLSQLazy步骤数多层 CTE 窗口函数边界4 步排序→累计→汇总→选列核心技巧晦涩的 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING直观的“降序 累计求和”可读性低需要理解偏移窗口高步骤即思考过程调试方式手动拆解 CTE反复运行单步执行每一步中间结果可见跨数据库需手动调整方言差异编译器自动生成对应语法这个实例展示了 SQLazy 处理“按事件重置的累计”类问题的自然性通过一个简单的排序技巧加上累计求和就能把复杂的分组逻辑拆解为清晰的动作。