从关于分组的前一行中减去一个值
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
我有以下 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