针对部分不同组的动态平均值计算

时间:2014-06-17 15:37:13

标签: mysql

我们有一张表格,代表特定SKU的购买。假设它有4列,PurchaseNo,SKU,QTY和PRICE。

QTY列表示每次特定购买所涉及的SKU编号。 PRICE列表示针对特定购买的每个单元支付的美元价值。

我们需要一个查询来确定所有当前“库存”AG1TBA的平均价格。

让我们假设当前库存的QTY 已知 200.我们还假设此表的前3行具有以下QTY和PRICE信息:50,22 | 120,21 | 96,25 |。

由于我们只有200个库存,我们不知何故需要查询来计算所有50个(22美元),120个(21美元)和96个中的30个(25美元)的平均值。显然,此处的平均价格为21.85美元,但查询如何动态修改自身以将平均值的计算限制为先前交易的特定金额(在本例中为200)。

以下是此假设表的图像: an image of this hypothetical table

1 个答案:

答案 0 :(得分:0)

假设您的表名为endurion,您可以使用以下语句解决它:

SET @stock := 200.0;
SET @amount := 0;

SELECT
    SUM(e1.costs)/@stock as average_price_per_unit
FROM
(
    SELECT 
        e.PurchaseNo,
        e.SKU,
        e.QTY,
        @amount := @amount + e.QTY,
        CASE 
            WHEN @amount <= @stock THEN e.QTY
            ELSE e.QTY + @stock - @amount
        END as part,
        e.PRICE,
        CASE 
            WHEN @amount <= @stock THEN e.QTY * e.PRICE
            ELSE (e.QTY + @stock - @amount) * e.PRICE
        END as costs
    FROM (
        SELECT
            *
        FROM
            endurion e1               -- replace your table name here
        WHERE
            SKU = 'AG1TBA'
        ORDER BY PurchaseNo DESC
    ) AS e    
    WHERE
        @amount <= @stock
) as e1;

<强>解释

最里面的Subselect

SELECT
    *
FROM
    endurion e1
WHERE
    SKU = 'AG1TBA'
ORDER BY 
    PurchaseNo DESC

确保我们匹配最新的购买,因为正如您所述,这些将为我们提供当前的库存。

最外面的查询将为我们提供每单位库存的平均价格。这应该是显而易见的。

外部子查询按购买计算单位总数。如果这大于股票,则只有一部分对股票有贡献。此部分在案例陈述中计算,第二部分计算此单位的总价格。

<强>提示

完整查询适用于我安装的MySQL v5.6.16,但不适用于current sqlfiddle的v5.5.32。我会考虑插入

的结果
SELECT 
    e.PurchaseNo,
    e.SKU,
    e.QTY,
    @amount := @amount + e.QTY,
    CASE 
        WHEN @amount <= @stock THEN e.QTY
        ELSE e.QTY + @stock - @amount
    END AS part,
    e.PRICE,
    CASE 
        WHEN @amount <= @stock THEN e.QTY * e.PRICE
        ELSE (e.QTY + @stock - @amount) * e.PRICE
    END AS costs
FROM (
    SELECT
        *
    FROM
        endurion e1               -- replace your table name here
    WHERE
        SKU = 'AG1TBA'
    ORDER BY PurchaseNo DESC
) AS e    
WHERE
    @amount <= @stock

进入临时表并通过此临时表计算平均值。