简体   繁体   English

从mysql中的前一行减去值

[英]Subtract value from previous row in mysql

I have table with the following structure我有以下结构的表

ID  VALUE
1   100
2   200
3   300
4   400
5   500

I want output like this我想要这样的输出

ID  VALUE  DIFF_to_Prev
1   100     0
2   200    100 
3   300    100 
4   400    100
5   500    100

This is the query I've tried so far这是我迄今为止尝试过的查询

SET @LastVALUE:= 0;
SET @LastSN:= 0;

SELECT dtr.SN, dtr.VALUE, 
       IF(@LastSN = dtr.SN, dtr.Value - @LastVALUE, 0) DIFF_to_Prev     
    FROM difftworows as dtr

This is the results I get from it:这是我从中得到的结果:

ID      VALUE   DIFF_to_Prev
1       100     0
2       200     0
3       300     0
4       400     0
5       500     0

I want to know what I'm doing wrong.我想知道我做错了什么。 Please tell me how can I fix it with suggestions.请告诉我如何通过建议修复它。

Thanks!!谢谢!!

Of course you a getting 0 in this column, you are not giving the parameter any value..当然,您在此列中得到 0,您没有为参数提供任何值..

If the ID's are continuously and 3 will always be previous of 4 , and 4 of 5 and ETC... then it can be done with a join:如果 ID 是连续的,并且 3 将始终是 4 的前一个,以及 5 中的 4 和 ETC ......那么它可以通过连接来完成:

SELECT t.id,t.value,t.value-coalese(s.value,0) as DIFF_to_Prev
FROM YourTable t
LEFT OUTER JOIN YourTable s ON(t.id = s.id + 1)

Eg:例如:

SELECT x.*
     , COALESCE(x.value-@prev,0) diff_to_prev
     , @prev:=value  
  FROM my_table x
     , (SELECT @prev:=null) vars 
 ORDER 
    BY id;
SET @LastVALUE:= 0;
SELECT dtr.ID, dtr.VALUE, 
    0 - @LastVALUE + (@LastVALUE := dtr.VALUE) DIFF_to_Prev     
FROM difftworows as dtr
ORDER BY dtr.ID

If first Diff really needs to be 0:如果第一个 Diff 确实需要为 0:

SET @LastVALUE:= NULL;
SELECT dtr.ID, dtr.VALUE,
  CASE 
    WHEN @LastVALUE IS NULL THEN 0 * (@LastVALUE := dtr.VALUE)
    ELSE 0 - @LastVALUE + (@LastVALUE := dtr.VALUE)
  END DIFF_to_Prev
FROM difftworows as dtr
ORDER BY dtr.ID

Without using user variables不使用用户变量

SELECT sub0.ID, 
        sub0.VALUE,
        sub0.VALUE - (COALESCE(d2a.VALUE, sub0.VALUE)) AS DIFF_to_Prev
FROM
(
    SELECT d1.ID, d1.VALUE, MAX(d2.ID) AS d2_max_id
    FROM difftworows d1
    LEFT OUTER JOIN difftworows d2
    ON d1.ID > d2.ID
    GROUP BY d1.ID, d1.VALUE
) sub0
LEFT OUTER JOIN difftworows d2a
ON sub0.d2_max_id = d2a.ID
ORDER BY sub0.ID

EDIT - avoiding the sub query:-编辑 - 避免子查询: -

SELECT d1.ID, 
        d1.VALUE,
        d1.VALUE - IF(COUNT(d2.ID) = 0, d1.VALUE, SUBSTRING_INDEX(GROUP_CONCAT(d2.VALUE ORDER BY d2.ID DESC), ',', 1)) AS DIFF_to_Prev
FROM difftworows d1
LEFT OUTER JOIN difftworows d2
ON d1.ID > d2.ID
GROUP BY d1.ID, 
        d1.VALUE

I'll revive it, as now there is way better way to do it - in mysql 8+ there are window functions for such a problems.我会恢复它,因为现在有更好的方法来做到这一点 - 在 mysql 8+ 中,有针对此类问题的窗口函数。 For this situation you could use lag, like here: https://learnsql.com/blog/difference-between-two-rows-in-sql/对于这种情况,您可以使用延迟,例如: https : //learnsql.com/blog/difference-between-two-rows-in-sql/

For you itd be:对你来说是:

VALUE - LAG(VALUE) OVER (ORDER BY ID ) AS DIFF_to_Prev

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

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