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

SQL Server中关联查询无结果时的库存计算问题

SQL Server中关联查询无结果时的库存计算问题

我明白你的问题啦!你的库存计算逻辑本身是对的,但现在卡在两个尴尬的场景:一是最后一次盘点后到目标日期之间没任何库存变动,关联查询直接查不到数据;二是有些产品压根没做过盘点记录,连初始库存的来源都没有。咱们一步步来解决这两个问题:

核心思路调整

咱们需要把初始库存(最后一次盘点或默认0)和后续变动的逻辑拆开,用LEFT JOIN替代原来的INNER JOIN,确保哪怕没有后续变动,初始库存的记录也能保留;同时还要处理“无盘点记录”的情况,给这类产品一个默认的初始库存0。

完整解决方案SQL

WITH LastInventory AS (
    -- 第一步:找出每个产品+仓库的最后一次盘点日期
    SELECT 
        CodArt, 
        CodAlm, 
        MAX(FecDoc) AS LastInvDate
    FROM MOVSTOCKS
    WHERE TipDoc = 'IN'
    GROUP BY CodArt, CodAlm

    UNION ALL

    -- 第二步:补充没有盘点记录的产品+仓库组合,给个极早的日期(确保所有变动都能被计算)
    SELECT 
        DISTINCT CodArt, 
        CodAlm, 
        CAST('1900-01-01' AS DATE) AS LastInvDate
    FROM MOVSTOCKS
    WHERE NOT EXISTS (
        SELECT 1 
        FROM MOVSTOCKS inv
        WHERE inv.CodArt = MOVSTOCKS.CodArt 
          AND inv.CodAlm = MOVSTOCKS.CodAlm 
          AND inv.TipDoc = 'IN'
    )
),
InitialStock AS (
    -- 第三步:获取对应初始库存,无盘点记录则默认0
    SELECT 
        li.CodArt, 
        li.CodAlm,
        COALESCE(mv.UnidadesStock, 0) AS InitialStock,
        li.LastInvDate
    FROM LastInventory li
    LEFT JOIN MOVSTOCKS mv 
        ON li.CodArt = mv.CodArt 
        AND li.CodAlm = mv.CodAlm 
        AND li.LastInvDate = mv.FecDoc 
        AND mv.TipDoc = 'IN'
)
-- 第四步:计算最终库存
SELECT 
    isc.CodArt,
    mv.DescArt,
    isc.CodAlm,
    isc.InitialStock + COALESCE(SUM(mv.EntranStock), 0) - COALESCE(SUM(mv.SalenStock), 0) AS Stock
FROM InitialStock isc
LEFT JOIN MOVSTOCKS mv 
    ON isc.CodArt = mv.CodArt 
    AND isc.CodAlm = mv.CodAlm 
    AND mv.FecDoc > isc.LastInvDate  -- 只统计盘点后的变动
    AND mv.FecDoc <= '2022-06-01'   -- 目标日期
    AND mv.TipDoc IN ('EN', 'SL')   -- 只算入库和出库
WHERE isc.CodArt = 'C5'
GROUP BY isc.CodArt, mv.DescArt, isc.CodAlm, isc.InitialStock
ORDER BY isc.CodArt, isc.CodAlm;

代码解释

  1. LastInventory CTE:先收集所有有盘点记录的产品+仓库的最后盘点日期,再补充那些从未做过盘点的组合,给它们一个早于所有可能业务日期的初始日期,这样后续计算时能包含所有历史变动。
  2. InitialStock CTE:把最后盘点日期对应的库存取出来,没有盘点记录的产品直接设初始库存为0,避免空值问题。
  3. 主查询:用LEFT JOIN关联初始库存和后续变动记录,哪怕没有变动,初始库存的行也会保留;用COALESCE把SUM返回的NULL转成0,确保计算结果不会变成空值。

验证你的示例数据

用你提供的数据测试这个SQL,会得到你预期的结果:

CodArtDescArtCodAlmStock
C5Palet19
C5Palet21

哪怕最后一次盘点后没有任何库存变动,这个查询也能正确返回初始库存值;如果某个产品没有任何盘点记录,也会从0开始计算所有入库减出库的总和。

备注:内容来源于stack exchange,提问作者antoine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 07:19:08