如何在 MySQL 5.7 分组和排序中获取上一行值

How can I get previous row value in MySQL 5.7 grouping and ordering by

我有一个类似这样的数据集:

TABLE TIMELINE

student_id course_id date progress
50 1 2022-01-01 0.1
50 1 2022-01-02 0.3
50 1 2022-01-03 0.7
50 3 2022-01-01 0.2
50 3 2022-01-02 0.3
50 3 2022-01-03 0.9
73 2 2022-01-01 0.1
73 2 2022-01-02 0.4

这已经是一个查询(因此,最终查询中的一个子查询),它通过时间戳对所有进度进行分组。我只是按 DATE(以及 student_idcourse_id)分组并得到 MAX(progress) 以便将粒度设置为 STUDENT - COURSE - DATE.

我需要检索每门课程的每个学生每天的进度。

那么,在那种情况下:

student_id course_id date progress progress_of_day
50 1 2022-01-01 0.1 0.1
50 1 2022-01-02 0.3 0.2
50 1 2022-01-03 0.7 0.4
.... ..... ..... ..... .....

progress of day 是当天取得的进度减去前一天取得的进度

我设法使用带有条件的简单 JOIN 使它工作:

timeline t1 LEFT JOIN timeline t2 
ON t1.student_id = t2.student_id 
AND t1.course_id = t2.course_id
AND t1.date > t2.date ## <---- THE SOLUTION BUT ALSO THE PROBLEM

所以我可以从 t1 中得到 MAX(progress),从 t2 中得到 MAX(progress),然后简单地减去它们

但这表现不佳。实际上,我不能使用它,timeline table 很大,我们唯一的索引是 student_id,所以比较每一行之间的日期是疯狂的。我设法与几个学生和 LIMIT 一起完成了这项工作。

预期结果:与此相同,但表现良好。

我知道也许可以使用@variables,但我不知道如何进行。

想法?

谢谢

SELECT student_id,
       course_id,
       `date`,
       CASE WHEN @group = CONCAT(student_id, '-', course_id)
            THEN CAST(progress - @progress AS DECIMAL(2,1))
            ELSE progress
            END progress_of_day,
       @group := CONCAT(student_id, '-', course_id),
       @progress := progress progress
FROM timeline
CROSS JOIN ( SELECT @group := '', @progress := 0 ) variables
ORDER BY student_id, course_id, `date`

https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=650b940341e91b266fdd626bd4766566