从关于分组的前一行中减去一个值

Subtract a value from previous row respecting the grouping

我有以下 table:

CREATE TABLE `movm` (
    `id` INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `product` INTEGER NOT NULL,
    `value` DECIMAL(10, 2) NOT NULL
    -- ...
);

还有一些数据:

INSERT INTO `movm`(`product`, `value`) VALUES 
    (1, 1000),
    (1, -200),
    (1,  100),
    (2,   50),
    (2,  -10),
    (1,  100),
    (2,  -20);

我希望得到以下结果:

+----+---------+---------+----------+---------+
| id | product | value   | previous | current |
+----+---------+---------+----------+---------+
|  1 |       1 | 1000.00 |        0 |    1000 |
|  2 |       1 | -200.00 |     1000 |     800 |
|  3 |       1 |  100.00 |      800 |     900 |
|  6 |       1 |  100.00 |      900 |    1000 |
|  4 |       2 |   50.00 |        0 |      50 |
|  5 |       2 |  -10.00 |       50 |      40 |
|  7 |       2 |  -20.00 |       40 |      20 |

但始终尊重GROUP BY产品

我尝试了以下 SQL:

SELECT
    `id`,
    `product`,
    `value`,
    @previous := (@current)           AS `previous`,
    @current  := (@current + `value`) AS `current`
    FROM
        `movm`,
        (
            SELECT
                @previous := 0,
                @current  := 0
        ) AS `__movm`;

因为它不尊重分组依据,所以它总是对所有内容求和,并且没有决胜局。

已经做了IF(@product != product, @current := 0, NULL);有效,但没有那么灵活。而且我还需要只跟踪该产品的值,绕过任何顺序,如您所见,它们没有排序(我认为这很容易解决在子查询中包装当前 SQL ).

所以:有没有更好的解决方案,我可以使用它 GROUP BY product 并获得如图所示的预期结果?

您需要另一个变量来跟踪产品,还需要 order by 以便您可以更改 product 变量并在产品值更改时重置 counters

这会起作用。

SELECT
    id,
    product,
    value,
    @previous := IF( @prevProduct = product,@current,0)           AS previous,
    @current  := IF( @prevProduct = product, @current + value, value) AS current,
    @prevProduct := product as var_val 
    FROM
    movm,
        (
            SELECT
                @previous := 0,
                @current  := 0,
                @prevProduct := NULL
        ) AS `__movm`
    ORDER BY product