[英]How to get the difference between consecutive rows in MySQL?
I have a table in mysql database this data.
id date number qty
114 07-10-2018 200 5
120 01-12-2018 300 10
123 03-02-2019 700 12
1126 07-03-2019 1000 15
I want to calculate difference between two consecutive rows and i need output format be like:
id date number diff qty avg
114 07-10-2018 200 0 5 0
120 01-12-2018 300 100 10 10
123 03-02-2019 700 400 12 33.33
1126 07-03-2019 1000 300 15 20
Any one know how to do this in mysql query?有谁知道如何在 mysql 查询中做到这一点? I want first value of diff and avg column to be 0 and rest is the difference.我希望 diff 和 avg 列的第一个值为 0,其余的就是差异。
For MySQL 8 then use Lag window function.对于MySQL 8,则使用滞后窗口函数。
SELECT
test.id,
test.date,
test.number,
test.qty,
IFNULL(test.number - LAG(test.number) OVER w, 0) AS diff,
ROUND(IFNULL(test.number - LAG(test.number) OVER w, 0)/ test.qty, 2) AS 'Avg'
FROM purchases test
WINDOW w AS (ORDER BY test.`date` ASC);
For MySQL 5.7 or lesser version对于 MySQL 5.7 或更低版本
We can use the MySQL variable to do this job.我们可以使用MySQL 变量来完成这项工作。 Consider your table name is test
.考虑您的表名是test
。
SELECT
test.id,
test.date,
test.number,
test.qty,
@diff:= IF(@prev_number = 0, 0, test.number - @prev_number) AS diff,
ROUND(@diff / qty, 2) 'avg',
@prev_number:= test.number as dummy
FROM
test,
(SELECT @prev_number:= 0 AS num) AS b
ORDER BY test.`date` ASC;
-------------------------------------------------------------------------------
Output:
| id | date | number| qty | diff | avg | dummy |
-----------------------------------------------------------------
| 114 | 2018-10-07 | 200 | 5 | 0 | 0.00 | 200 |
| 120 | 2018-12-01 | 300 | 10 | 100 | 10.00 | 300 |
| 123 | 2019-02-03 | 700 | 12 | 400 | 33.33 | 700 |
| 1126 | 2019-03-07 | 1000 | 15 | 300 | 20.00 | 1000 |
Explaination:说明:
(SELECT @prev_number:= 0 AS num) AS b
we initialized variable @prev_number to zero in FROM clause and joined with each row of the test table. (SELECT @prev_number:= 0 AS num) AS b
我们在FROM 子句中将变量@prev_number初始化为零,并与测试表的每一行连接。@diff:= IF(@prev_number = 0, 0, test.number - @prev_number) AS diff
First we are generating difference and then created another variable diff to reuse it for average calculation. @diff:= IF(@prev_number = 0, 0, test.number - @prev_number) AS diff
首先我们生成差异,然后创建另一个变量diff以将其重用于平均值计算。 Also we included one condition to make the diff for first row as zero.我们还包括一个条件,使第一行的差异为零。@prev_number:= test.number as dummy
we are setting current number to this variable, so it can be used by next row. @prev_number:= test.number as dummy
我们将当前数字设置为这个变量,所以它可以被下一行使用。Note : We have to use this variable first, in both difference as well as average and then set to the new value, so next row can access value from the previous row.注意:我们必须首先在差值和平均值中使用此变量,然后设置为新值,以便下一行可以访问上一行的值。
You can skip/modify order by
clause as per your requirements.您可以根据您的要求跳过/修改order by
子句。
There could be better ways to do this, but try this:可能有更好的方法来做到这一点,但试试这个:
SELECT A.id,
A.date,
A.number,
A.qty,
A.diff,
B.avg
FROM
(SELECT *, abs(LAG(number, 1, number) OVER (ORDER BY id) - number) AS 'diff'
FROM table) AS A
JOIN
(SELECT *, abs(LAG(number, 1, number) OVER (ORDER BY id) - number)/qty AS 'avg' FROM table) AS B
ON A.id = B.id;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.