需要有关SQL Server的帮助;更新缺少的开始和结束库存值的最简单方法是什么?显示的值是该周的已验证数字。
$order = new Order();
$order->parent_id = $parent->id;
$order->school_id = $schoolId;
if($order->save()){
foreach($json["packs"] as $pack){
$order->packs()->attach($pack["pack_id"], ["child_name" => $pack["child_name"]]);
foreach($pack["optional_products"] as $optionalProduct){
$order->packs()->optionalProducts()->attach($optionalProduct["pack_optional_product_id"]);
}
}
return response()->json(["status" => "ok", "order_id" => $order->id]);
}else{
return response()->json(["status" => "failed"]);
}
答案 0 :(得分:0)
几个窗口函数可以为您提供结果。当您在ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
子句中指定ORDER BY
时,OVER
是默认作用域,但是,由于另一个窗口函数已明确声明了该作用域,并且未使用默认作用域,因此展示很重要;正如您所看到的区别。
WITH VTE AS(
SELECT *
FROM (VALUES ( 1,1001,100,-10),
( 2,1001,NULL, 0),
( 3,1001, 90, 0),
( 4,1001,NULL, 20),
( 5,1001,NULL,100),
( 6,1001,NULL,-20),
( 7,1001,NULL, 0),
( 8,1001,200, 10),
( 9,1001,NULL, 0),
(10,1001,NULL,-50),
(11,1001,NULL, 0)) V(Week, ItemNr, [Begin],Increase))
SELECT Week,
ItemNr,
ISNULL([Begin],S.Starting + SUM(Increase) OVER (PARTITION BY ItemNr ORDER BY Week ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)) AS [Begin],
Increase,
S.Starting + SUM(Increase) OVER (PARTITION BY ItemNr ORDER BY Week ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [End]
FROM VTE V
CROSS APPLY (SELECT TOP 1 [Begin] AS Starting
FROM VTE ca
WHERE ca.ItemNr = V.ItemNr
ORDER BY Week ASC) S;
注意:这似乎是某种库存系统。值得注意的是,这没有考虑到库存水平可能会出错。例如,假设某物品被盗;在这些事件中,[End]
和[Begin]
的值(当其值为NULL
时)是错误的。如果需要考虑这一点,那么我们需要在问题中知道这一点。
编辑:解决“遗失”股票的解决方案。这样,这将获得库存和总量的最后“已知”值。因此,对于本示例,在第1周中,尽管“出售”了10件商品,但第2周的开始时的开始值显示为35。这意味着缺少5件商品(被盗?)。这需要影响所有未来的库存水平。这样就得到:
WITH VTE AS(
SELECT *
FROM (VALUES ( 1,1001,100,-10),
( 2,1001,NULL, 0),
( 3,1001, 90, 0),
( 4,1001,NULL, 20),
( 5,1001,NULL,100),
( 6,1001,NULL,-20),
( 7,1001,NULL, 0),
( 8,1001,200, 10),
( 9,1001,NULL, 0),
(10,1001,NULL,-50),
(11,1001,NULL, 0),
(1,1002,50,-10),
(2,1002,35,0),--Begin value lowered. Some items went "missing"
(3,1002,NULL,5),
(4,1002,40,10)) V(Week, ItemNr, [Begin],Increase))
SELECT Week,
ItemNr,
[Begin],
Increase,
LastKnown,
WeekKnown,
ISNULL([Begin],S.LastKnown + SUM(Increase) OVER (PARTITION BY ItemNr, WeekKnown ORDER BY Week ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)) AS ActualBegin,
ISNULL([Begin],S.LastKnown + SUM(Increase) OVER (PARTITION BY ItemNr, WeekKnown ORDER BY Week ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) AS [End]
FROM VTE V
CROSS APPLY (SELECT TOP 1 [Begin] AS LastKnown, Week AS WeekKnown
FROM VTE ca
WHERE ca.ItemNr = V.ItemNr
AND ca.Week <= V.Week
AND ca.[Begin] IS NOT NULL
ORDER BY Week DESC) S
ORDER BY V.ItemNr, V.Week;
答案 1 :(得分:0)
这也是另一种方式
SELECT T1.Week,
T1.ItemNr,
CASE WHEN T1.[Begin] IS NULL THEN
(SELECT MAX([Begin]) + SUM(Increase) FROM @T WHERE Week < T1.Week AND ItemNr = T1.ItemNr)
ELSE
T1.[Begin]
END [Begin],
T1.Increase,
CASE WHEN T1.[Begin] IS NULL THEN
(SELECT MAX([Begin]) + SUM(Increase) FROM @T WHERE Week < T1.Week AND ItemNr = T1.ItemNr)
ELSE
T1.[Begin]
END + T1.Increase [End]
FROM @T T1;
返回:
+------+--------+-------+----------+-----+
| Week | ItemNr | Begin | Increase | End |
+------+--------+-------+----------+-----+
| 1 | 1001 | 100 | -10 | 90 |
| 2 | 1001 | 90 | 0 | 90 |
| 3 | 1001 | 90 | 0 | 90 |
| 4 | 1001 | 90 | 20 | 110 |
| 5 | 1001 | 110 | 100 | 210 |
| 6 | 1001 | 210 | -20 | 190 |
| 7 | 1001 | 190 | 0 | 190 |
| 8 | 1003 | 200 | 10 | 210 |
| 9 | 1003 | 210 | 0 | 210 |
| 10 | 1003 | 210 | -50 | 160 |
| 11 | 1003 | 160 | 0 | 160 |
+------+--------+-------+----------+-----+