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

基于每日库存报表编写SQL实现库存出库统计的方法

实现每日出库产品/数量报表的SQL方案

没问题!完全可以通过SQL来实现这个每日出库报表的需求,我来给你拆解思路并提供可行的查询方案。

先理清楚需求场景

你提到的两种出库情况,其实可以归纳成两类:

  • 场景1:同一个InboundID+ArticleCode的组合,第二天的库存比前一天少了,减少的数值就是出库量
  • 场景2:前一天还在库存报表里的InboundID+ArticleCode组合,第二天直接消失了,那前一天的库存总量就是全部出库的数量

我们可以用SQL Server的窗口函数(LAG)来关联连续两天的库存数据,或者用自连接的方式,这里用窗口函数会更简洁高效,适合SQL Server 2012及以后的版本。

先明确表结构

假设你的库存报表存在一个叫DailyInventory的表,结构大概是这样的(建议把Date字段设为DATE类型,别用字符串的'yesterday'/'today',日期计算会更靠谱):

CREATE TABLE DailyInventory (
    ArticleCode VARCHAR(50),
    Description VARCHAR(100),
    InboundID INT,
    TotalStock INT,
    [Date] DATE
);

直接上可用的SQL查询

下面这个查询可以直接用来生成当日的出库报表,我会给你拆解每个部分的作用:

WITH InventoryWithPrevDay AS (
    SELECT 
        ArticleCode,
        Description,
        InboundID,
        TotalStock,
        [Date],
        -- 拉取同一组合前一天的库存数量
        LAG(TotalStock) OVER (
            PARTITION BY ArticleCode, InboundID 
            ORDER BY [Date]
        ) AS PrevDayStock,
        -- 拉取前一天的日期,用来确认是连续的统计日
        LAG([Date]) OVER (
            PARTITION BY ArticleCode, InboundID 
            ORDER BY [Date]
        ) AS PrevDayDate
    FROM DailyInventory
)
SELECT 
    ArticleCode,
    Description,
    InboundID,
    -- 计算出库量:如果当天没这条记录,就用前一天的库存;否则用前一天减当天的库存
    CASE 
        WHEN TotalStock IS NULL THEN PrevDayStock
        ELSE PrevDayStock - TotalStock
    END AS Gone,
    -- 出库日期统一为我们要统计的当日
    COALESCE([Date], DATEADD(DAY, 1, PrevDayDate)) AS [Date]
FROM (
    -- 先处理场景1:当日有记录,且库存比前一天少
    SELECT 
        ArticleCode,
        Description,
        InboundID,
        TotalStock,
        [Date],
        PrevDayStock,
        PrevDayDate
    FROM InventoryWithPrevDay
    WHERE 
        [Date] = CAST(GETDATE() AS DATE) -- 锁定今日的报表数据
        AND PrevDayStock IS NOT NULL -- 确保前一天有这个组合的记录
        AND PrevDayStock > TotalStock -- 库存确实减少了

    UNION ALL

    -- 再处理场景2:前一天有记录,但今日完全没了这个组合
    SELECT 
        d1.ArticleCode,
        d1.Description,
        d1.InboundID,
        NULL AS TotalStock,
        NULL AS [Date],
        d1.TotalStock AS PrevDayStock,
        d1.[Date] AS PrevDayDate
    FROM DailyInventory d1
    LEFT JOIN DailyInventory d2 
        ON d1.ArticleCode = d2.ArticleCode 
        AND d1.InboundID = d2.InboundID 
        AND d2.[Date] = CAST(GETDATE() AS DATE)
    WHERE 
        d1.[Date] = DATEADD(DAY, -1, CAST(GETDATE() AS DATE)) -- 前一天的报表数据
        AND d2.ArticleCode IS NULL -- 今日找不到这个组合的记录
) AS CombinedOutbound
WHERE Gone > 0 -- 只输出确实有出库的记录
ORDER BY ArticleCode, InboundID;

对应你的样本数据验证

用你给的样本数据跑这个查询,正好能得到你想要的结果:

  • 前日的BAM131-L库存是550,今日降到500,出库50(场景1)
  • 前日的BAM135-L(InboundID 53800300,库存2)今日消失,出库2(场景2)

结果会是这样:

+-------------+------------------------------+-----------+------------+-----------+
| ArticleCode | Description                  | InboundID | Gone       | Date      |
+-------------+------------------------------+-----------+------------+-----------+
| BAM131-L    | Jacket in piqu? Georgia L    | 53800222  | 50         | today     |
| BAM135-L    | Coat Leather Jumper L        | 53800300  | 2          | today     |
+-------------+------------------------------+-----------+------------+-----------+

一些小提醒

  1. 如果你的Date字段是字符串(比如'yesterday'),记得先转成DATE类型,比如用CASE [Date] WHEN 'yesterday' THEN DATEADD(DAY,-1,GETDATE()) WHEN 'today' THEN GETDATE() END来转换。
  2. 如果要统计其他日期的出库报表,把GETDATE()换成目标日期就行,比如'2024-05-20'。
  3. 要是需要批量统计历史数据,可以调整WHERE条件,覆盖多个日期范围。

内容的提问来源于stack exchange,提问作者Barnabás Kriszt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:09:05