【问题标题】:Stock ageing with SQL Server使用 SQL Server 进行库存老化
【发布时间】:2018-05-10 13:40:13
【问题描述】:

我有一个表格内容如下,其中'ItemName'是物品的名称,'CurrentStock'是物品的当前库存数量,所有其他列是当年的入库和出库总和.现在我想用 0 替换所有负值,并以 FIFO 顺序用正值调整这些负值。谁能指导我如何在 SQL Server 中做到这一点。

这是预期的结果

一开始我是这样尝试的

select ItemName,CurrentStock, 
case when (Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013)<0 and (Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013+Qnty2012andBefore)>=0 then (Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013+Qnty2012andBefore) 
    when (Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013)<0 and (Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013+Qnty2012andBefore)>=0 THEN (Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013+Qnty2012andBefore)
    when (Qnty2016+Qnty2015+Qnty2014+Qnty2013)<0 and (Qnty2016+Qnty2015+Qnty2014+Qnty2013+Qnty2012andBefore)>=0 THEN (Qnty2016+Qnty2015+Qnty2014+Qnty2013+Qnty2012andBefore)
    when (Qnty2015+Qnty2014+Qnty2013)<0 and (Qnty2015+Qnty2014+Qnty2013+Qnty2012andBefore)>=0 THEN (Qnty2015+Qnty2014+Qnty2013+Qnty2012andBefore)
    when (Qnty2014+Qnty2013)<0 and (Qnty2014+Qnty2013+Qnty2012andBefore)>=0 THEN (Qnty2014+Qnty2013+Qnty2012andBefore)
    when Qnty2013 <0 and Qnty2013+Qnty2012andBefore >=0 then Qnty2013+Qnty2012andBefore 
else Qnty2012andBefore end as Qnty2012andBefore,
case when Qnty2013<0 then 0
    when (Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014)<0 and (Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013)>=0 then (Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013) 
    when (Qnty2017+Qnty2016+Qnty2015+Qnty2014)<0 and (Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013)>=0 THEN (Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013)
    when (Qnty2016+Qnty2015+Qnty2014)<0 and (Qnty2016+Qnty2015+Qnty2014+Qnty2013)>=0 THEN (Qnty2016+Qnty2015+Qnty2014+Qnty2013)
    when (Qnty2015+Qnty2014)<0 and (Qnty2015+Qnty2014+Qnty2013)>=0 THEN (Qnty2015+Qnty2014+Qnty2013)
    when (Qnty2014)<0 and (Qnty2014+Qnty2013)>=0 THEN (Qnty2014+Qnty2013)
else Qnty2013 end as Qnty2013,
case when Qnty2014<0 then 0
    when (Qnty2018+Qnty2017+Qnty2016+Qnty2015)<0 and (Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014)>=0 then (Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014) 
    when (Qnty2017+Qnty2016+Qnty2015)<0 and (Qnty2017+Qnty2016+Qnty2015+Qnty2014)>=0 THEN (Qnty2017+Qnty2016+Qnty2015+Qnty2014)
    when (Qnty2016+Qnty2015)<0 and (Qnty2016+Qnty2015+Qnty2014)>=0 THEN (Qnty2016+Qnty2015+Qnty2014)
    when (Qnty2015)<0 and (Qnty2015+Qnty2014)>=0 THEN (Qnty2015+Qnty2014)
else Qnty2014 end as Qnty2014,
case when Qnty2015<0 then 0
    when (Qnty2018+Qnty2017+Qnty2016)<0 and (Qnty2018+Qnty2017+Qnty2016+Qnty2015)>=0 then (Qnty2018+Qnty2017+Qnty2016+Qnty2015) 
    when (Qnty2017+Qnty2016)<0 and (Qnty2017+Qnty2016+Qnty2015)>=0 THEN (Qnty2017+Qnty2016+Qnty2015)
    when (Qnty2016)<0 and (Qnty2016+Qnty2015)>=0 THEN (Qnty2016+Qnty2015)
else Qnty2015 end as Qnty2015,
    case when Qnty2016<0 then 0
    when (Qnty2018+Qnty2017)<0 and (Qnty2018+Qnty2017+Qnty2016)>=0 then (Qnty2018+Qnty2017+Qnty2016) 
    when (Qnty2017)<0 and (Qnty2017+Qnty2016)>=0 THEN ( Qnty2017+Qnty2016)
else Qnty2016 end as Qnty2016,
case when Qnty2017<0 then 0
    when (Qnty2018)< 0 and (Qnty2018+Qnty2017)>=0 then (Qnty2018+Qnty2017) 
else Qnty2017 end as Qnty2017,
case when Qnty2018<0 then 0 else Qnty2018 end as Qnty2018 FROM StockTable

但它给出了这样的错误输出

谢谢

【问题讨论】:

  • Eek,您可以选择规范化表格吗?有了数量和日期,这将变得更加简单......
  • @JacobH 你能解释一下怎么做吗,谢谢。
  • 我无法理解这一点现在我想用 0 替换所有负值,并用 FIFO 顺序中的正值调整这些负值。你能解释一下吗?
  • @Mr.拉赫曼,我试图解释我想要什么。 2012年的库存是4246,2013年没有库存只有446缺货,所以2013年之后我的库存是(4246-446)=3800,这是2012年的库存。2014年没有缺货但1233库存所以我的现在的库存是 (3800 +1233)=5033,其中 2012 年的 3800 和 2014 年的 1233。同样在 2015 年没有库存,1139 库存在,所以 2015 年之后我的库存是 (5033-1139)=3894,其中 ( 3800-1139)=2012 年的 2661 和 2014 年的 1233 。等等 2016 年、2017 年和 2018 年。我不知道这是在解释这种情况还是让你更困惑。无论如何,谢谢你的帮助。

标签: sql sql-server stock inventory


【解决方案1】:

可能有两种解决方案。

  1. 如下图使用#Temp表

    SELECT ItemName,CurrentStock,
    CASE when Qnty2018<0 THEN 0 ELSE Qnty2018 END as Qnty2018,
    CASE when Qnty2017<0 THEN 0 ELSE Qnty2017 END as Qnty2017,
    CASE when Qnty2016<0 THEN 0 ELSE Qnty2016 END as Qnty2016,
    CASE when Qnty2015<0 THEN 0 ELSE Qnty2015 END as Qnty2015,
    CASE when Qnty2014<0 THEN 0 ELSE Qnty2014 END as Qnty2014,
    CASE when Qnty2013<0 THEN 0 ELSE Qnty2013 END as Qnty2013,
    CASE when Qnty2012andBefore<0 THEN 0 ELSE Qnty2012andBefore END as Qnty2012andBefore INTO #Temp FROM StockTable
    
    update #Temp set Qnty2018=CurrentStock WHERE Qnty2018<>0 AND Qnty2017=0 AND Qnty2016=0 AND Qnty2015=0 AND Qnty2014=0 AND Qnty2013=0 AND Qnty2012andBefore=0
    update #Temp set Qnty2017=CurrentStock-Qnty2018 WHERE Qnty2017<>0 AND Qnty2016=0 AND Qnty2015=0 AND Qnty2014=0 AND Qnty2013=0 AND Qnty2012andBefore=0
    update #Temp set Qnty2016=CurrentStock-Qnty2018+Qnty2017 WHERE Qnty2016<>0 AND Qnty2015=0 AND Qnty2014=0 AND Qnty2013=0 AND Qnty2012andBefore=0
    update #Temp set Qnty2015=CurrentStock-Qnty2018+Qnty2017+Qnty2016 WHERE Qnty2015<>0 AND Qnty2014=0 AND Qnty2013=0 AND Qnty2012andBefore=0
    update #Temp set Qnty2014=CurrentStock-Qnty2018+Qnty2017+Qnty2016+Qnty2015 WHERE Qnty2014<>0 AND Qnty2013=0 AND Qnty2012andBefore=0
    update #Temp set Qnty2013=CurrentStock-Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014 WHERE Qnty2013<>0 AND Qnty2012andBefore=0
    update #Temp set Qnty2012andBefore=CurrentStock-Qnty2018+Qnty2017+Qnty2016+Qnty2015+Qnty2014+Qnty2013 WHERE Qnty2012andBefore<>0
    SELECT * FROM #Temp
    

    2.使用游标,您可以逐行迭代并编写逻辑。由于在 SQL 中不建议这样做,因此只有在没有其他选项时才使用它。

【讨论】:

  • @sticky bit 您的建议可能会导致比预期更多的列数,并且列的顺序可能会产生误导
  • 感谢您的建议,我将尝试这两个。
  • 对于这么晚的回复,我深表歉意。我使用了临时表并根据我的要求对其进行了更新,它给了我准确的结果,感谢您的建议。
  • 该特定代码不起作用,但该方法确实对我有用。
【解决方案2】:

您认为您需要CASEs 中的总和来做什么?鉴于您的示例,在我看来,每一列上的 CASE 具有您想要的效果。对于 Qnty2012andBefore 的计算,从 CurrentStock 中减去,再次单独对加法应用 CASE。像这样:

SELECT ItemName,
       CurrentStock,
       CASE
         WHEN Qnty2018 < 0
           THEN 0
         ELSE
           Qnty2018
       END Qnty2018,
       ...
       CASE
         WHEN Qnty2013 < 0
           THEN 0
         ELSE
           Qnty2013
       END Qnty2013,
       CurrentStock
       -
       CASE
         WHEN Qnty2018 < 0
           THEN 0
         ELSE
           Qnty2018
       END
       ...
       -
       CASE
         WHEN Qnty2013 < 0
           THEN 0
         ELSE
           Qnty2013
       END Qnty2012andBefore
       FROM StockTable;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-29
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多