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

I have a dataset similar to this:

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

This is already a query (so, a subquery in the final query) that group all the progress through the timestamp. I just grouped by DATE (and student_id and course_id) and got the MAX(progress) in order to have the granularity set to STUDENT - COURSE - DATE.

I need to retrieve the progress for each day for each student for each course.

So, in that case:

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
.... ..... ..... ..... .....

The progress of day is the progress achieved that day minus progress achieved previous day

I managed to get this working using a simple JOIN with conditions:

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

So I could get MAX(progress) out of t1 and MAX(progress) out of t2 and simple subtract them

BUT this isn't performing well. Actually, I can't use it, the timeline table is massive and the only indexes we have is on student_id, so comparing the date between each row is insane. I managed to make this work with a few students and with LIMIT.

Expected result: the same I would achieve with this, but performing well.

I know maybe it is possible to do with @variables, but I don't know how to proceed.

Ideas?

Thanks


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