SQL Server:填充稀疏值

时间:2018-11-17 11:51:36

标签: sql-server

需要有关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"]);
}
  • 如果“开始”为NULL,则上周结束
  • END =开始+增加

2 个答案:

答案 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 |
+------+--------+-------+----------+-----+

Demo