Db2 for IBM i如何用基础SELECT实现累计和达阈值时停止查询
问题结论
完全可以实现,仅使用基础SELECT语法即可满足需求,不需要额外写存储过程、不需要写入权限,适配你当前Db2 for IBM i的只读访问环境。
实现注意前提
SQL表本身没有内置的固有顺序,你提到的「按表中顺序逐行选取」必须指定明确的排序依据字段(比如条目自增ID、创建时间戳、业务定义的序号字段等),否则数据库返回记录的顺序是不确定的,累计求和的逻辑会出错。下文示例统一用entry_id作为排序字段,你实际使用时替换成业务中确定先后顺序的真实字段即可。
实现逻辑
通过窗口函数逐行计算金额列的累计滚动和,先取出所有累计和未达到阈值的记录,再补上第一条把累计和推到阈值及以上的记录,即可得到要求的结果集,逻辑覆盖所有边界场景:
- 某条记录累计和刚好等于阈值:正常返回该条及之前所有记录,不会多取后续数据
- 单条记录金额就超过阈值:仅返回这一条记录
- 全表记录金额总和都达不到阈值:返回全表所有记录
示例代码
假设你的业务表名为order_items,金额列为price,预设阈值为9.00美元,排序字段为entry_id,代码如下:
WITH record_with_running_total AS ( SELECT *, SUM(price) OVER ( ORDER BY entry_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_sum FROM order_items -- 如果需要提前过滤参与计算的记录,可以在这里加WHERE条件 ) -- 先取所有累计和未达阈值的记录 SELECT * FROM record_with_running_total WHERE cumulative_sum <= 9.00 UNION ALL -- 补上第一条让累计和跨过阈值的记录 SELECT * FROM ( SELECT * FROM record_with_running_total WHERE cumulative_sum > 9.00 ORDER BY entry_id FETCH FIRST 1 ROW ONLY ) AS overflow_record -- 最终对合并后的结果按顺序排序返回 ORDER BY entry_id
效果验证
举个测试场景:表中按entry_id排序的price值依次为3.00、2.50、4.00、1.50,计算得到的累计和分别为3.00、5.50、9.50、11.00:
- 第一部分查询返回前2条累计和为3.00、5.50的记录(均<=9.00)
- 第二部分查询取第一条累计和>9.00的记录,也就是第三条累计和为9.50的记录
- 最终返回3条记录,累计总金额9.50,满足「累计到>=9.00即停止取数」的要求,不会返回第四条记录。
内容的提问来源于stack exchange,提问作者Logan Price
相关产品推荐
相关产品推荐

