如何编写SQL脚本按指定累计值筛选库存估值数据?
基于收货日期的库存估值SQL实现方案
我明白你要解决的是月末库存估值的问题——取最后收货货物的指定总和来计算剩余库存价值。咱们一步步来拆解解决方案:
现有基础查询
你已经有了简化后的联合查询语句:
SELECT DATE, W1 FROM Table ORDER BY DATE DESC
返回的结果如下:
| 行号 | DATE | W1 |
|---|---|---|
| 1 | 2019-02-28 00:00:00 | 13250 |
| 2 | 2019-02-28 00:00:00 | 42610 |
| 3 | 2019-02-28 00:00:00 | 41170 |
| 4 | 2019-02-28 00:00:00 | 13180 |
| 5 | 2019-02-28 00:00:00 | 20860 |
| 6 | 2019-02-28 00:00:00 | 19870 |
| 7 | 2019-02-28 00:00:00 | 37780 |
| 8 | 2019-02-28 00:00:00 | 47210 |
| 9 | 2019-02-28 00:00:00 | 32000 |
| 10 | 2019-02-28 00:00:00 | 41930 |
累计和思路的进展
你已经想到用累计和来推进,计算后的结果如下:
| 行号 | DATE | W1 | 累计和 |
|---|---|---|---|
| 1 | 2019-02-28 00:00:00 | 13250 | 13250 |
| 2 | 2019-02-28 00:00:00 | 42610 | 55860 |
| 3 | 2019-02-28 00:00:00 | 41170 | 97030 |
| 4 | 2019-02-28 00:00:00 | 13180 | 110210 |
| 5 | 2019-02-28 00:00:00 | 20860 | 131070 |
| 6 | 2019-02-28 00:00:00 | 19870 | 150940 |
| 7 | 2019-02-28 00:00:00 | 37780 | 188720 |
| 8 | 2019-02-28 00:00:00 | 47210 | 235930 |
| 9 | 2019-02-28 00:00:00 | 32000 | 267930 |
| 10 | 2019-02-28 00:00:00 | 41930 | 309860 |
参数化筛选的解决方案
要实现指定目标值(比如120000)时,返回累计和恰好达到该值的行(最后一行取部分W1),可以用CTE结合窗口函数来实现。这里用ROW_NUMBER()保证排序稳定性(因为你的DATE都是同一天,需要行号固定顺序):
-- 定义目标参数,可替换为任意需要的值 DECLARE @TargetSum INT = 120000; WITH InventoryWithRunningTotal AS ( SELECT ROW_NUMBER() OVER (ORDER BY DATE DESC) AS 行号, DATE, W1, SUM(W1) OVER (ORDER BY DATE DESC, ROW_NUMBER() OVER (ORDER BY DATE DESC)) AS 累计和 FROM Table ) SELECT 行号, DATE, W1, 累计和, -- 判断当前行取全部W1还是剩余部分 CASE WHEN 累计和 <= @TargetSum THEN W1 ELSE @TargetSum - (累计和 - W1) END AS W1_Select FROM InventoryWithRunningTotal -- 筛选出需要包含的行:累计和减去当前W1后仍小于目标值 WHERE (累计和 - W1) < @TargetSum;
逻辑说明
- 用
ROW_NUMBER()生成稳定行号,确保同一天的记录排序固定; - 用
SUM() OVER()窗口函数按收货日期倒序(最新收货在前)计算累计和; - 通过
CASE语句分支处理:若当前累计和未超目标值,取全部W1;若超过,取目标值与前一行累计和的差值(即需要的剩余部分); WHERE条件确保只保留前几行全部数据,加上最后一行(其累计和超目标值,但前一行未超)。
当目标值设为120000时,执行结果会和你期望的一致:
| 行号 | DATE | W1 | 累计和 | W1_Select |
|---|---|---|---|---|
| 1 | 2019-02-28 00:00:00 | 13250 | 13250 | 13250 |
| 2 | 2019-02-28 00:00:00 | 42610 | 55860 | 42610 |
| 3 | 2019-02-28 00:00:00 | 41170 | 97030 | 41170 |
| 4 | 2019-02-28 00:00:00 | 13180 | 110210 | 13180 |
| 5 | 2019-02-28 00:00:00 | 20860 | 131070 | 9790 |
这样就能精准得到你需要的指定总和的库存估值数据了。
内容的提问来源于stack exchange,提问作者yongsheng
相关产品推荐
相关产品推荐

