如何计算每个零件编号从当前日期到当前日期 - 交货时间的订单数量?

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

我正在尝试编写一个查询来计算两个日期(订单日期和回溯日期(订单日期 - 交货时间))之间每个零件编号的订单数量之和。

例如,

零件编号 订购日期 回顾日期 交货时间 订购数量 总订单
A 2023年1月20日 2023年10月1日 10 2 3
A 2023年1月15日 2023年1月5日 10 1 1

我本质上是想计算“总订单”列....

这是我当前的查询,并且在 Between 函数之后使用“Lead Time”时不断收到错误。

 select 
    "Part Number",
    "Snapshot Date",
    sum("Lead Time"),
    sum("Order Qty") over (partition by "Part Number" order by 
    "Snapshot Date" desc rows between "Lead Time" preceding and current 
    row) as "Total Demand"
  from table1

我的源数据结构如下:

快照日期 零件编号 交货时间 订购数量
2022年1月1日 A 15 0
2022年1月1日 B 10 1
2022年1月2日 A 15 1
2022年1月2日 B 10 0
2022年1月3日 A 15 5
2022年1月3日 B 10 3
sql partitioning snowflake-schema
1个回答
0
投票

我明白你想用窗口函数做什么。不幸的是,您无法为每个窗口指定要查看的动态行范围。 ROWS 还指定了行数和您想要的天数(相对于您的订单/快照日期)。

这里的技巧是计算 LookbackDate,然后匹配 LookbackDate 和 Snapshot 日期内的所有相关 SnapshotDate。然后你可以聚合得到总数。因此本质上需要“自加入”。

我的以下解决方案是 T-SQL 中的。但除了临时表语法之外的所有内容都应该在 Snowflake 中工作。

--Create some data to work with
DROP TABLE IF EXISTS #InputData;
CREATE TABLE #InputData(SnapshotDate DATE NOT NULL
                    , PartNum CHAR(1) NOT NULL
                    , LeadTime BIGINT NOT NULL
                    , OrderQty BIGINT NOT NULL
                    )
INSERT INTO #InputData(SnapshotDate
                    , PartNum
                    , LeadTime
                    , OrderQty
                    )
SELECT CONVERT(DATE, X.SnapshotDate, 105)
    , X.PartNum
    , X.LeadTime
    , X.OrderQty
FROM (VALUES
            ('01-01-2022', 'A', 15, 0)
            , ('01-01-2022', 'B', 10, 1)
            , ('01-02-2022', 'A', 15, 1)
            , ('01-02-2022', 'B', 10, 0)
            , ('01-03-2022', 'A', 15, 5)
            , ('01-03-2022', 'B', 10, 3)
            
    ) X(SnapshotDate
        , PartNum
        , LeadTime
        , OrderQty
        );

    
/*
IMPORTANT ASSUMPTION: The combination of SnapshotDate and PartNum is unique.
*/      

--4. Finally do a 1 to 1 Join back onto your orginal dataset, to include the total and the lookback date.
SELECT inp.PartNum
    , inp.SnapshotDate
    , subq2.LookbackDate
    , inp.LeadTime
    , inp.OrderQty
    , subq2.OrderQtyInLastLeadManyDays
FROM #InputData inp
INNER JOIN (
    --3. Sum the order quantity for each snapshot date, lookback date and part num.
    SELECT subq.SnapshotDate
        , subq.LookbackDate
        , subq.PartNum
        , SUM(inp.OrderQty) AS OrderQtyInLastLeadManyDays
    FROM #InputData inp
    INNER JOIN(
        --1. lets create the lookback date from the SnapshotDate and the LeadTime
        SELECT SnapshotDate
            , DATEADD(DAY, -LeadTime, SnapshotDate) AS LookbackDate
            , PartNum
            , OrderQty
        FROM #InputData
        ) subq
        --2.Join the data set onto itself, where the SnapshotDate is within the date range (LookbackDate, SnapshotDate). Also make sure PartNum is the same...
        --I've chosen not to be inclusive on both ends (like a BETWEEN), as it didn't feel right. But you can easily change this if you wish.
        ON inp.SnapshotDate > subq.LookbackDate AND inp.SnapshotDate <= subq.SnapshotDate
            AND inp.PartNum = subq.PartNum
    GROUP BY subq.SnapshotDate
        , subq.LookbackDate
        , subq.PartNum
    ) subq2
    ON inp.SnapshotDate = subq2.SnapshotDate
        AND inp.PartNum = subq2.PartNum
ORDER BY inp.SnapshotDate ASC
    , inp.PartNum ASC;

自己在 db<>fiddle 上尝试一下。您可能想要更改输入数据集。就目前情况而言,没有什么“有趣”的事情发生。您的所有 SnapshotDate(对于同一 PartNum)大约相隔 30 天。但是,您的交货时间不到 30 天。尝试一下这些值,看看这是否能回答您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.