使用 SQL 服务器的库存时效
Stock ageing with SQL Server
我有一个table内容如下,其中'ItemName'是物品的名称,'CurrentStock'是物品的当前库存数量,所有其他列都是物品的总和当年的进货和出货。现在我想用 0 替换所有负值,并以 FIFO 顺序用正值调整这些负值。谁能指导我如何在 SQL 服务器中做到这一点。
这是预期结果
最初我是这样尝试的
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
但它给出了这样的错误输出
谢谢
您认为 CASE
中的总和有什么用?鉴于您的示例,在我看来,每个单独列上的 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;
对此可能有两种解决方案。
使用#Temp table 如下图
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.Using Cursor,你可以在行的基础上迭代并编写逻辑。因为在 SQL 中不推荐这样做,所以只有在没有其他选择时才使用它。
我有一个table内容如下,其中'ItemName'是物品的名称,'CurrentStock'是物品的当前库存数量,所有其他列都是物品的总和当年的进货和出货。现在我想用 0 替换所有负值,并以 FIFO 顺序用正值调整这些负值。谁能指导我如何在 SQL 服务器中做到这一点。
这是预期结果
最初我是这样尝试的
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
但它给出了这样的错误输出
谢谢
您认为 CASE
中的总和有什么用?鉴于您的示例,在我看来,每个单独列上的 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;
对此可能有两种解决方案。
使用#Temp table 如下图
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.Using Cursor,你可以在行的基础上迭代并编写逻辑。因为在 SQL 中不推荐这样做,所以只有在没有其他选择时才使用它。