Snowflake 中的 SQL 查询 - 计算每个日期库存的供应天数以及每天的预测

问题描述 投票:0回答:1

我想创建一个列来计算每个日期库存以及预测当天和之后的供应天数。

示例数据中,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
sql snowflake-cloud-data-platform cumulative-sum
1个回答
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

输出为

enter image description here

然后这个 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;

输出

enter image description here

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.