简体   繁体   English

计算mysql中行之间的差异之和

[英]Count the sum of the difference between rows in mysql

How do I calculate the difference between each row and return the total sum and also how to write it in a procedure.(I use mysql ) 如何计算每一行之间的差并返回总和,以及如何在过程中将其写入。(我使用mysql

(There will be gaps in the id column) (id列中将有空白)

id --- session --- value
1.........3..........15
4.........3...........5
7.........3...........8
10........3..........13
11........3...........9

From id.1 to id.4 difference is 10 从id.1到id.4的差是10
From id.2 to id.3 difference is 3 从id.2到id.3的差值为3
From id.3 to id.4 difference is 5 从id.3到id.4的差异是5
From id.4 to id.5 difference is 4 从id.4到id.5的差是4
The total sum is = 22 总和是= 22

This is what I have come up with: (and yes its completely wrong) 这就是我想出的:(是的,这是完全错误的)

SET @oldV = 0;

SELECT SUM(table.x)
FROM(
    SELECT @oldV := value AND IF(value > @oldV, @x:=(value - @oldV), @x:=(@oldV - value)) x
    FROM TheTable WHERE session = 3 ORDER BY id) table;

based on your example you seem to be calculating the absolute difference between rows. 根据您的示例,您似乎正在计算行之间的绝对差。 You can do this with a join statement. 您可以使用join语句执行此操作。 Try something like the following: 尝试如下操作:

select a.id,b.id,abs(a.value - b.value) as dif
from UserData as a 
inner join
UserData as b
on a.id = b.id - 1

then once you have the dif col you can do a sum. 那么一旦有了dif col,就可以求和。 If there are going to be gaps in the id create a new col ROWNUMBER which has no gaps and then use that instead of id as your on statement 如果id中有空格,请创建一个没有空格的新col ROWNUMBER,然后使用它代替id作为on语句

http://sqlfiddle.com/#!9/c4573/5 http://sqlfiddle.com/#!9/c4573/5

SELECT *, 
   IF(@prev IS NULL,0, @diff := ABS(`value`-@prev)),
      @prev:=`value`,
      @total:=IF(@total IS NULL,0,@total)+@diff
FROM table1
ORDER BY id

There's lots of ways to obtain the specified result. 有很多方法可以获取指定的结果。

One possibility (specific to MySQL) is to use a user-defined variable to store the "value" from the previous row, so you can compare that to the "value" from the current row. 一种可能性(特定于MySQL)是使用用户定义的变量来存储上一行的“值”,因此您可以将其与当前行的“值”进行比较。

Note: the behavior of MySQL user-defined variables in a statement like the one below is undefined. 注意:MySQL用户定义变量在以下语句中的行为是未定义的。 The MySQL Reference Manual warns against depending on the behavior of user-defined variables in a context like this. MySQL参考手册警告不要在这样的上下文中依赖用户定义变量的行为。 BUT... we do observe repeatable consistent behavior in MySQL 5.1 and 5.5. 但是...我们确实在MySQL 5.1和5.5中观察到了可重复的一致行为。

SELECT SUM(d.diff) AS tot_diff
  FROM ( SELECT ABS(t.`value`-@pvalue) AS diff
              , @pvalue := t.`value`
           FROM mytable t
          CROSS
           JOIN ( SELECT @pvalue := NULL ) i
          ORDER BY t.id
       ) d

Note that it's important that the user-defined variable be initialized, since the variable persists for the session, not just the statement. 请注意,初始化用户定义的变量很重要,因为该变量在会话中持久存在,而不仅仅是语句。 That's why we include the initialization in an inline view (derived table i ). 这就是为什么我们将初始化包含在内联视图(派生表i )中的原因。 Optionally, we could run a separate SET @pvalue := NULL; (可选)我们可以运行单独的SET @pvalue := NULL; statement before we run the query. 语句,然后运行查询。

I do not like it very much, but it seems to work. 我不太喜欢它,但它似乎起作用。

SELECT 
   SUM(
       ABS(t1.num - t2.num)
   ) AS sumofdiffs
   FROM sumdiff AS t1 
   JOIN sumdiff AS t2 
      ON(
          (SELECT MIN(id) FROM sumdiff AS t3 WHERE t3.id > t1.id) = t2.id
      )
;

Found another way. 找到了另一种方法。 Using just a subquery, no joins. 仅使用子查询,就没有联接。 It still is rather slow. 它仍然很慢。 But should be better thant the first query. 但是应该比第一个查询更好。

SELECT 
    SUM( 
        ABS( t1.num - 
            (SELECT num FROM sumdiff WHERE id > t1.id ORDER BY id ASC LIMIT 1 ) 
        )
    ) AS summofdiffs
FROM sumdiff AS t1;

SQLFiddle SQLFiddle

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

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