rows between current row and unbounded following 是窗口帧子句,表示从当前行到分区末尾的所有行,常用于计算“后续累计量”,如未来待出库总量;但它本身不执行减法,不能直接得出剩余库存,必须结合初始库存与后续出库累计量(如initial_stock - sum(qty) over(...))才能正确计算。

ROWS UNBOUNDED FOLLOWING 是什么,它不能直接算“剩余库存”
ROWS UNBOUNDED FOLLOWING 是窗口帧定义子句,只决定当前行在 OVER() 中“能看到哪些行”,本身不执行减法或累加。你想算“剩余库存”,本质是「初始库存量 − 已出库累计量」,必须配合 SUM() 或 LAG() 等聚合函数,且需明确业务逻辑顺序(比如按时间排序)。
正确写法:用 SUM() 配合 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
如果你有一张出库记录表 inventory_out,含字段 order_time、qty,而“剩余库存”指「从当前记录开始,往后所有出库量的总和」(即未来待出库量),那才是 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING 的典型场景:
SELECT
order_time,
qty,
SUM(qty) OVER (
ORDER BY order_time ASC
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
) AS remaining_out_qty
FROM inventory_out;
注意:ROWS UNBOUNDED FOLLOWING 单独写不合法,必须搭配 BETWEEN;UNBOUNDED FOLLOWING 指“直到最后一行”,不是“无限远”。
常见错误:把“剩余库存”误当成当前行之后的累计,却忘了初始库存
真实库存场景中,你通常有:initial_stock(期初库存)和一系列 out_qty(出库量)。直接对 out_qty 做 ROWS UNBOUNDED FOLLOWING 只得“后续出库总量”,不是“剩余库存”。正确做法是:
- 先用
SUM(out_qty) OVER (ORDER BY time ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)算后续出库 - 再用
initial_stock - COALESCE(后续出库, 0)得剩余库存 - 如果
initial_stock在每行重复,记得用FIRST_VALUE(initial_stock) OVER ()提取,避免分组干扰
兼容性坑:MySQL 8.0+ 和 PostgreSQL 支持,但 SQLite 不支持
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING 在 MySQL 8.0、PostgreSQL 11+、SQL Server 2012+ 中可用;SQLite 直到 3.25(2018)才支持窗口函数,且不支持 UNBOUNDED FOLLOWING —— 它会报错 near "FOLLOWING": syntax error。若需兼容 SQLite,只能用自连接或子查询模拟,性能差很多。
另外,ORDER BY 必须存在,否则 ROWS 帧无效;没有 ORDER BY 时,所有行被视为同一位置,UNBOUNDED FOLLOWING 失去意义。











