Snowflake中计算库存供应天数(DOS)的SQL查询问题
修正SQL以计算库存供应天数(DOS)
需求定义
库存供应天数(DOS)指当日库存可覆盖的后续日期Forecast总天数,规则如下:
- 从当日的次日开始,依次累加每日Forecast,直到累加总和超过当日库存时停止,统计已累加的天数
- 若当日库存不足以覆盖次日的Forecast,DOS为0
示例:
- 2025年1月23日库存700,可覆盖后续3天Forecast(200+300+100=600 ≤700),DOS为3
- 2025年1月24日库存600,可覆盖后续2天Forecast(300+100=400 ≤600),DOS为2
原始数据
| Location | Material | Start_Date | Inventory | Forecast |
|---|---|---|---|---|
| W01 | 123456 | 1/23/2025 | 700 | 400 |
| W01 | 123456 | 1/24/2025 | 600 | 200 |
| W01 | 123456 | 1/25/2025 | 400 | 300 |
| W01 | 123456 | 1/26/2025 | 450 | 100 |
| W01 | 123456 | 1/27/2025 | 50 | 300 |
期望输出
| Location | Material | Start_Date | Inventory | Forecast | DOS |
|---|---|---|---|---|---|
| W01 | 123456 | 1/23/2025 | 700 | 400 | 3 |
| W01 | 123456 | 1/24/2025 | 600 | 200 | 2 |
| W01 | 123456 | 1/25/2025 | 400 | 300 | 2 |
| W01 | 123456 | 1/26/2025 | 450 | 100 | 1 |
| W01 | 123456 | 1/27/2025 | 50 | 300 | 0 |
原SQL的问题
- 语法错误:多处子查询的
WHERE条件缺少闭合的双引号和括号,例如WHERE "B"."START_DATE" >= "A"."START_DATE - 逻辑错误:DOS计算用库存除以未来总需求,不符合“累加后续Forecast统计天数”的核心需求
- 关联缺失:未对
Location和Material做关联过滤,会导致跨物料/地点计算需求,违背业务逻辑 - 范围错误:
FUTURE_DEMAND包含了当日Forecast,但需求中是用库存覆盖次日及之后的Forecast
修正后的SQL
SELECT a.Location, a.Material, a.Start_Date, a.Inventory, a.Forecast, COUNT(b.Start_Date) AS DOS FROM your_table_name a LEFT JOIN your_table_name b ON a.Location = b.Location AND a.Material = b.Material AND b.Start_Date > a.Start_Date WHERE ( SELECT SUM(c.Forecast) FROM your_table_name c WHERE c.Location = a.Location AND c.Material = a.Material AND c.Start_Date > a.Start_Date AND c.Start_Date <= b.Start_Date ) <= a.Inventory GROUP BY a.Location, a.Material, a.Start_Date, a.Inventory, a.Forecast ORDER BY a.Start_Date;
注:将
your_table_name替换为实际表名
逻辑说明
- 通过自连接关联同物料、同地点的后续日期数据
- 对每个日期,累加其后续每日的Forecast,判断累加和是否不超过当日库存
- 统计满足条件的后续日期数量,即为DOS;若没有满足条件的日期,返回0
内容的提问来源于stack exchange,提问作者Yu Ching Tsoi
相关产品推荐
相关产品推荐

