我想创建一个列来计算每个日期库存以及预测当天和之后的供应天数。
示例数据中,1/23/2025 有 1000 个库存,计算在负数之前将减去预测天数。从 1/23/2025 到 1/25/2025 的预测总和为 700 等于 3 天。因此,1/23/2025是3天的供应
“FUTURE_DEMAND”只是所有需求的总和,但当 Projected_on_hand - sum(total_demand) 大于 0 时,我需要对预测进行求和
SELECT
"A"."LOCATION",
"A"."MATERIAL",
"A"."START_DATE",
"A"."PROJECTED_ON_HAND",
"A"."TOTAL_DEMAND",
(SELECT SUM("B"."TOTAL_DEMAND")
FROM "B"
WHERE "B"."START_DATE" >= "A"."START_DATE" ) AS "FUTURE_DEMAND",
CASE
WHEN (SELECT SUM("B"."TOTAL_DEMAND")
FROM "B"
WHERE "B"."START_DATE" >= "A"."START_DATE ) = 0 THEN NULL
ELSE "A"."PROJECTED_ON_HAND" /
(SELECT SUM ("B"."TOTAL_DEMAND")
FROM "B"
WHERE "B"."START_DATE" >= "A"."START_DATE
END AS "DOS"
FROM "A"
ORDER BY
"A"."START_DATE"
我正在尝试通过今天和之后的每日预测来计算每个日期的供应天数
数据表
地点 | 材质 | 开始_日期 | 预计_库存 | 预测 |
---|---|---|---|---|
W01 | 123456 | 2025 年 1 月 23 日 | 1000 | 400 |
W01 | 123456 | 2025 年 1 月 24 日 | 600 | 100 |
W01 | 123456 | 2025 年 1 月 25 日 | 500 | 200 |
W01 | 123456 | 2025 年 1 月 26 日 | 450 | 400 |
W01 | 123456 | 2025 年 1 月 27 日 | 50 | 100 |
预期结果 - DOC 计算的新列
地点 | 材质 | 开始_日期 | 预计_库存 | 预测 | 文档 |
---|---|---|---|---|---|
W01 | 123456 | 2025 年 1 月 23 日 | 1000 | 400 | 3 |
W01 | 123456 | 2025 年 1 月 24 日 | 600 | 100 | 2 |
W01 | 123456 | 2025 年 1 月 25 日 | 500 | 200 | 1 |
W01 | 123456 | 2025 年 1 月 26 日 | 450 | 400 | 1 |
W01 | 123456 | 2025 年 1 月 27 日 | 50 | 100 | 0 |
作为
rank_cumul_cte
CTE 的一部分,对所有行进行排名并计算每行的累积预测
SELECT location,material, start_date,forecast,projected_inventory,
ROW_NUMBER() OVER (PARTITION BY location,material ORDER BY start_date) AS rn,
SUM(forecast) OVER (PARTITION BY location,material ORDER BY start_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_forecast
FROM test
输出为
然后这个 CTE 是基于每一行与自身或更高排名进行比较(例如
2025-01-23
与自身比较(因为我们需要计算天数)以及所有高于它的日期)进行自连接。
还有一个比较条件,即该行的project_inventory 应高于净累积预测
a.projected_inventory - (b.cumulative_forecast - a.cumulative_forecast + a.forecast) >= 0
另一个条件是检查日期的预测是否小于库存,则 DOC 应为 0
CASE
WHEN a.projected_inventory < a.forecast THEN 0
最终查询
WITH rank_cumul_cte AS (
SELECT location,material, start_date,forecast,projected_inventory,
ROW_NUMBER() OVER (PARTITION BY location,material ORDER BY start_date) AS rn,
SUM(forecast) OVER (PARTITION BY location,material ORDER BY start_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_forecast
FROM test
)
SELECT a.location,a.material,a.start_date,a.projected_inventory,a.forecast,
CASE
WHEN a.projected_inventory < a.forecast THEN 0
ELSE COUNT(b.start_date)
END AS DOC
FROM rank_cumul_cte a
LEFT JOIN
rank_cumul_cte b
ON
a.location = b.location
AND a.material = b.material
AND b.rn >= a.rn
AND a.projected_inventory - (b.cumulative_forecast - a.cumulative_forecast + a.forecast) >= 0
--
GROUP BY
a.location,a.material, a.start_date, a.projected_inventory, a.forecast
ORDER BY
a.start_date;
输出