简体   繁体   English

SQL中如何计算之前的累计乘积(详见下文)

[英]How calculate previous cumulative product in SQL (detail below)

I'm trying to estimate a new scrap rate (loss factor) in a production line using SQL.我正在尝试使用 SQL 估算生产线中的新报废率(损失系数)。

Basically, there are several operation in one machine, with qty in and qty out for each one of the operation.基本上,一台机器有多个操作,每个操作都有 qty in 和 quty out。

The following operation has, as qty in, the qty out of the previous operation.以下操作具有前一个操作的数量,作为 qty in。

And this scrap rate (loss factor) needs to be carry over the operation.而这个报废率(损耗因子)需要结转操作。

So, operation 1 will have qty out / qty in from operation 1 = scrap rate 1;因此,操作 1 将有来自操作 1 的输出数量/输入数量 = 报废率 1; operation 2 has qty out / qty in * scrap rate 1;操作 2 的出货量/进货量 * 报废率 1; and so on.等等。

I know I can use "exp(sum(log(column)) OVER (ORDER BY column))" to get the overall, lets say machine scrap rate, but I need to have an cumulative per machine-operation level.我知道我可以使用“exp(sum(log(column)) OVER (ORDER BY column))”来获得整体,比如说机器报废率,但我需要每个机器操作级别的累积值。

Hope the image attached can explain better the outcome.希望所附图片可以更好地解释结果。

I'm struggling to calculate the column G (OutFactorAccumulated) in the image.我正在努力计算图像中的 G 列(OutFactorAccumulated)。 Hope someone can help me.希望可以有人帮帮我。

data and expected results example数据和预期结果示例

Thanks,谢谢,

calculate cumulative product计算累计积

I think you are most of the way there.我认为你大部分时间都在那里。

The final step is simply to take the OutfactorAccumulated column, and do a similar windowed function over it to calculate the next column eg, MIN(OutFactorAccumulated) OVER (PARTITION BY Machine) .最后一步是简单地获取 OutfactorAccumulated 列,并对其执行类似的窗口函数以计算下一列,例如MIN(OutFactorAccumulated) OVER (PARTITION BY Machine)

Note also that the other windowed function (the SUM) should also have a PARTITION BY Machine in the window to ensure that each machine only uses its own data.另请注意,另一个窗口函数(SUM)也应该在窗口中有一个PARTITION BY Machine ,以确保每台机器只使用自己的数据。

Here is a db<>fiddle with the example code below in SQL Server/T-SQL.这是一个db<>fiddle ,其中包含 SQL Server/T-SQL 中的示例代码。

  • The last CTE 'MachineData_with_ExpQtyOut` is the one that has the windows MIN function to do the calculation.最后一个 CTE“MachineData_with_ExpQtyOut”是具有 Windows MIN 函数来进行计算的 CTE。
  • In the Fiddle I have also added a second machine B1 with some data I made up - to demonstrate it works with multiple machines.在 Fiddle 中,我还添加了第二台机器 B1,其中包含我编写的一些数据 - 以证明它适用于多台机器。

(Note lots of CAST AS decimal(14,10) to match your data - there's probably a better way to do this). (请注意很多 CAST AS decimal(14,10) 以匹配您的数据 - 可能有更好的方法来执行此操作)。

CREATE TABLE #MachData (Machine nvarchar(10), Operation int, QtyIn int, QtyOut int, PRIMARY KEY (Machine, Operation));
INSERT INTO #MachData (Machine, Operation, QtyIn, QtyOut) VALUES
(N'A1', 1, 100, 100),
(N'A1', 2, 100, 95),
(N'A1', 3, 95,  95),
(N'A1', 4, 95,  94),
(N'A1', 5, 94,  86),
(N'A1', 6, 86,  66),
(N'A1', 7, 66,  66),
(N'A1', 8, 66,  66),
(N'A1', 9, 66,  66);

WITH MachData_with_Factors AS
    (SELECT     Machine, 
                Operation, 
                QtyIn, 
                QtyOut, 
                CAST(1 - CAST(QtyOut AS decimal(14,10))/CAST(QtyIn AS decimal(14,10)) AS decimal(14,10)) AS LossFactor,
                CAST(CAST(QtyOut AS decimal(14,10))/CAST(QtyIn AS decimal(14,10)) AS decimal(14,10)) AS OutFactor
        FROM    #MachData   
    ),
    MachineData_with_Acc AS
    (SELECT     *,
                CAST(exp(SUM(log(OutFactor)) OVER (PARTITION BY Machine ORDER BY Operation)) AS decimal(14,10)) AS OutFactorAccumulated
        FROM    MachData_with_Factors
    ),
    MachineData_with_ExpQtyOut AS
    (SELECT     *,
                CAST(OutFactorAccumulated * 100.0 / MIN(OutFactorAccumulated) OVER (PARTITION BY machine) AS decimal(14,10)) AS NewExpectedQtyOut
        FROM    MachineData_with_Acc
    )
SELECT *
    FROM    MachineData_with_ExpQtyOut
    ORDER BY Machine, Operation;

Results are as below结果如下

Machine  Operation  QtyIn       QtyOut  LossFactor    OutFactor     OutFactorAccumulated  NewExpectedQtyOut
------------------------------- ---------------------------------------------------------------------------
A1       1          100         100     0.0000000000  1.0000000000  1.0000000000          151.5151515152
A1       2          100         95      0.0500000000  0.9500000000  0.9500000000          143.9393939394
A1       3          95          95      0.0000000000  1.0000000000  0.9500000000          143.9393939394
A1       4          95          94      0.0105263158  0.9894736842  0.9400000000          142.4242424242
A1       5          94          86      0.0851063830  0.9148936170  0.8600000000          130.3030303030
A1       6          86          66      0.2325581395  0.7674418605  0.6600000000          100.0000000000
A1       7          66          66      0.0000000000  1.0000000000  0.6600000000          100.0000000000
A1       8          66          66      0.0000000000  1.0000000000  0.6600000000          100.0000000000
A1       9          66          66      0.0000000000  1.0000000000  0.6600000000          100.0000000000

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM