简体   繁体   中英

Calculate new value in MariaDB based on values in the previous row

In MariaDB 10.3, I have a table like this:

id date sum
1 2020-01-01 120
1 2020-02-01 130
1 2020-03-01 140
1 2020-04-01 150
1 2020-05-01 160
1 2020-06-01 170

I need to calculate the remaining sum after every date. Something like this. I need the calculation to happen as a query in the MariaDB.

id date sum remaining total sum before pay
1 2020-01-01 120 870
1 2020-02-01 130 750
1 2020-03-01 140 620
1 2020-04-01 150 480
1 2020-05-01 160 330
1 2020-06-01 170 170

I found a few close solutions but can't alter them in a proper way to suit my need. Any ideas would be appreciated.

The logic for the last column is:

  1. The first value is the whole sum owed (120+130+140...)
  2. Every next value is calculated from that number decreased by the value in the sum column on the same row ie
  • 870-120=750;
  • 750-130=620;
  • 620-140=480; etc.

My attempt was:

  1. First queries which were close, but didn't work:
    SELECT 
    id,s.sum,s.date,
    @b := @b + s.sum   AS balance
    FROM
    (SELECT @b := 0.0) AS dummy 
      CROSS JOIN
        tpp AS s
        where id=1
    ORDER BY
        s.date ;

The result was:

id date sum remaining total sum before pay
1 2020-01-01 120 120
1 2020-02-01 130 250
1 2020-03-01 140 380
1 2020-04-01 150 520
1 2020-05-01 160 670
1 2020-06-01 170 840

Ie it kind of reversed the result. And increased the value with the value on the next row.

  1. The other query was with the LAG function but the subtracting part was disappointing
    SELECT 
    id,date,
    sum(sum)-LAG(sum) OVER (ORDER BY date) AS l
    FROM tpp
    where id=1
    group by date,id
    ORDER BY date

And the result:

id date remaining total sum before pay
1 2020-01-01 null
1 2020-02-01 10
1 2020-03-01 10
1 2020-04-01 10
1 2020-05-01 10
1 2020-06-01 10

It subtracted:

  • 130-120=10;
  • 140-130=10;
  • 150-140=10; etc.

You need only SUM() window function:

SELECT id, date,
       SUM(sum) OVER (ORDER BY date DESC) AS l
FROM tpp
WHERE id = 1
ORDER BY date

See the demo .
Results:

> id | date       |   l
> -: | :--------- | --:
>  1 | 2020-01-01 | 870
>  1 | 2020-02-01 | 750
>  1 | 2020-03-01 | 620
>  1 | 2020-04-01 | 480
>  1 | 2020-05-01 | 330
>  1 | 2020-06-01 | 170

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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