Original request

$sql = "SELECT date, val1, val2, val3 FROM `$table` ORDER BY date ASC"; 

You need to make a query similar to the original with 3 additional virtual columns containing previous values ​​(if any), something like this:

  $sql2 = "SELECT date, val1, val2, val3, prev_val1, prev_val2, prev_val3 FROM `$table` ORDER BY date ASC"; 

OR more ideally, a query containing the difference between the current value and the previous value.

  $sql3 = "SELECT date, (val1 - prev_val1) AS val12, (val2 - prev_val2) AS val22, (val3 - prev_val3) AS val32 FROM `$table` ORDER BY date ASC"; 

If the cells contain values, they are integer. NULLs may be missing or equal to 0. NOT negative.

    2 answers 2

     SELECT date, val1-@pval1 as diff1, val2-@pval2 as diff2, val3-@pval3 as diff3, @pval1:=val1 as val1, @pval2:=val2 as val2, @pval3:=val3 as val3 FROM `$table`, (select @pval1:=NULL, @pval2:=NULL, @pval3:=NULL) A ORDER BY date ASC 

    Variables should receive new values after their previous values ​​have been used. Because all actions are performed from left to right. First, val1-@pval1 , and then @pval1 assigned a value from the current line to stay in it until the next.

    • Thanks, it works perfectly! What is the letter "A" before ORDER? - Andrey
    • @Andrey This is the name (alias) of the subquery that is in front of it in brackets. MySQL requires the name to be - Mike

    In MS SQL and DB2 there is a special function for this - lag (). In MySQL, you can get out through saving the value in a variable. Here is an example from an English SO:
    https://stackoverflow.com/a/11316349/272885
    Well, and other similar examples look at the phrase "mysql simulate lag"