You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SCD Type 2表的SQL Server近12个月末库存查询求助

查询SCD Type 2表的过去12个月末库存数据

问题背景

现有一张库存快照表(SCD Type 2结构),需要提取过去12个月每个月末的库存数据,部分月份无快照记录时需按规则填充(如无数据则取0)。

表结构

DateProductSupplierStock on Hand
202208241978906315225427
202206071978906315225428
202205141978906315225428
202205071978906315225426
202205041978906315225427
202205021978906315225424
202204271978906315225429
202204231978906315225430
202204221978906315225420
20211216197890631522540
20211214197890631522541
20211209197890631522540
20211208197890631522541
20211207197890631522543
20211206197890631522546
202112041978906315225413
202112031978906315225414
202112011978906315225415
202111261978906315225414
20210712197890631522540

预期输出

DateProductSupplierStock on Hand
202207311978906315225428
202206301978906315225428
202205311978906315225428
202204301978906315225429
20220331197890631522540
20220228197890631522540
20220131197890631522540
20211231197890631522540
202111301978906315225414

解决方案

核心思路:先生成过去12个月的月末日期列表,再为每个月末日期匹配该日期之前最新的库存记录,无匹配记录时填充0。

通用SQL实现

WITH 
-- 1. 生成过去12个月的月末日期序列
month_end_dates AS (
    SELECT 
        LAST_DAY(DATE_SUB(CURRENT_DATE(), INTERVAL n MONTH)) AS month_end_date
    FROM 
        UNNEST(GENERATE_ARRAY(0, 11)) n
),
-- 2. 为每条库存记录标记所属的产品-供应商组合,并按日期排序
ranked_inventory AS (
    SELECT 
        Date,
        Product,
        Supplier,
        `Stock on Hand`,
        ROW_NUMBER() OVER (PARTITION BY Product, Supplier ORDER BY Date DESC) AS rn
    FROM 
        inventory_table
)
-- 3. 关联日期序列与库存数据,取每个月末之前的最新库存
SELECT 
    FORMAT_DATE('%Y%m%d', med.month_end_date) AS Date,
    ri.Product,
    ri.Supplier,
    COALESCE(ri.`Stock on Hand`, 0) AS `Stock on Hand`
FROM 
    month_end_dates med
LEFT JOIN LATERAL (
    SELECT 
        Product, Supplier, `Stock on Hand`
    FROM 
        ranked_inventory ri
    WHERE 
        PARSE_DATE('%Y%m%d', ri.Date) <= med.month_end_date
        AND ri.Product = '19789063' -- 若需所有产品,可去掉此条件并关联产品维度表
        AND ri.Supplier = '152254' -- 若需所有供应商,可去掉此条件并关联供应商维度表
    ORDER BY 
        ri.Date DESC
    LIMIT 1
) ri ON TRUE
ORDER BY 
    med.month_end_date DESC;

代码说明

  1. 生成月末日期序列:用GENERATE_ARRAY生成0到11的数字,对应过去12个月,通过LAST_DAY获取每个月的最后一天。
  2. 排序库存记录:用ROW_NUMBER()按产品-供应商分组,按日期倒序排序,方便后续取最新记录。
  3. 关联匹配:通过LATERAL JOIN为每个月末日期找到最近的库存记录,用COALESCE处理无记录的情况,填充0。
  4. 格式转换:将日期格式转为YYYYMMDD格式,与原表保持一致。

适配不同数据库的调整

  • 若使用MySQL:替换GENERATE_ARRAY为递归CTE生成日期序列,PARSE_DATE替换为STR_TO_DATE。
  • 若使用SQL Server:GENERATE_ARRAY替换为递归CTE,LAST_DAY替换为EOMONTH,FORMAT_DATE替换为FORMAT。

内容的提问来源于stack exchange,提问作者Diego

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:19:20