I would like a cumulative DR or CR balance for the following table:
x
+-----------+--------------+---------------+---------+
| id | Date | DR | CR |
+-----------+--------------+---------------+---------+
| 1 | 2020-01-01 | 100 | 0 |
| 2 | 2020-01-01 | 200 | 0 |
| 3 | 2020-01-02 | 0 | 200 |
| 4 | 2020-01-02 | 0 | 50 |
| 5 | 2020-01-03 | 20 | 0 |
+-----------+--------------+---------------+---------+
For the above table, a cumulative Balance
column would be:
+-----------+--------------+---------------+---------+----------+
| id | Date | DR | CR | Balance |
+-----------+--------------+---------------+---------+----------+
| 1 | 2020-01-01 | 100 | 0 | 100 DR |
| 2 | 2020-01-01 | 200 | 0 | 300 DR |
| 3 | 2020-01-02 | 0 | 300 | 0 DR |
| 4 | 2020-01-02 | 0 | 50 | 50 CR |
| 5 | 2020-01-03 | 20 | 0 | 30 CR |
+-----------+--------------+---------------+---------+----------+
Decreasing a DR below 0 makes it a CR
Decreasing a CR below 0 makes it a DR
Where balance is 0, value is 0 DR
It could be calculated as CR’s being a negative value, but I would like the ‘DR’ and ‘CR’ text to show in the balance column after an abs
numerical value.
mysql Ver 14.14 Distrib 5.7.23, for Linux (x86_64) using EditLine wrapper
Thanks for your help
Advertisement
Answer
If you are running MySQL 8.0, you can use window functions:
select
t.*,
concat(
abs(sum(dr - cr) over(order by date, id)),
' ',
case when sum(dr - cr) over(order by date, id) >= 0 then 'DR' else 'CR' end
) balance
from mytable t
In earlier versions, one efficient option uses a session variable:
set @sm = 0;
select id, date, dr, cr, concat(abs(bal), ' ', case when bal >= 0 then 'DR' else 'CR' end) balance
from (
select
t.*,
@sm := @sm + dr - cr bal
from (select t.* from mytable t order by date, id) t
) t
Demo on DB Fiddle – both queries yield:
| id | date | dr | cr | balance |
| --- | ---------- | --- | --- | ------- |
| 1 | 2020-01-01 | 100 | 0 | 100 DR |
| 2 | 2020-01-01 | 200 | 0 | 300 DR |
| 3 | 2020-01-02 | 0 | 300 | 0 DR |
| 4 | 2020-01-02 | 0 | 50 | 50 CR |
| 5 | 2020-01-03 | 20 | 0 | 30 CR |