mysql - 在 mysql 或更好的 algothrim 中将每笔交易的借方与贷方相匹配?

标签 mysql sql algorithm user-accounts banking

首先让我解释一下表结构和我需要的输出。

userid  date           amount 
123    2017-01-01         5 
123    2017-01-03         2 
124    2017-01-04         2 
124    2017-01-04         3 
123    2017-01-05         -2

借方交易为负数,正数交易为成员(member)贷方交易。 通过这个查询我们可以很容易的制作出对帐单

select date as BookingDate,
       if(amount<0,amount,0) as Debit_Amount,
       if(amount>0,amount,0) as Credit_Amount,
       (@runtot :=  amount  + @runtot) AS Balance  
from transactions,
     (SELECT @runtot:=0) c 
where userid=123


BookingDate  Debit_Amount  Credit_Amount  Balance 
2017-01-01    0                 5           5 
2017-01-03    0                 2           7 
2017-01-05   -2                0           5

我的要求是使用 FIFO 方法根据借记交易标记每笔交易已支付或部分支付。像这样。这可能通过 mysql 查询还是使用更好的算法?

 userid  date           amount   status
    123    2017-01-01         5   partial_paid(-2)
    123    2017-01-03         2 
    124    2017-01-04         2 
    124    2017-01-04         3 
    123    2017-01-05         -2

谢谢

最佳答案

MariaDB [sandbox]> create table t(userid  int,dt date,  amount int);
Query OK, 0 rows affected (0.28 sec)

MariaDB [sandbox]> truncate table t;
Query OK, 0 rows affected (0.20 sec)

MariaDB [sandbox]> insert into t values
    -> (123  ,  '2017-01-01'  ,       5) ,
    -> (123  ,  '2017-01-03'  ,       2 ),
    -> (124  ,  '2017-01-04'  ,       2) ,
    -> (124  ,  '2017-01-04'  ,       3 ),
    -> (123  ,  '2017-01-05'  ,       -2),
    -> (125  ,  '2017-01-01'  ,       5) ,
    -> (125  ,  '2017-01-03'  ,       2 ),
    -> (125  ,  '2017-01-05'  ,       -6),
    -> (126  ,  '2017-01-01'  ,       5) ,
    -> (126  ,  '2017-01-02'  ,       -10),
    -> (126  ,  '2017-01-03'  ,       2 ),
    -> (126  ,  '2017-01-05'  ,       -10),
    -> (126  ,  '2017-01-06'  ,       13);
Query OK, 13 rows affected (0.06 sec)
Records: 13  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]>
MariaDB [sandbox]>
MariaDB [sandbox]> select s.userid,s.dt,s.amount,
    ->  case when s.crs is null then 0 else s.crs end crs,
    ->  case when s.exhaust is null then 0 else s.exhaust end exhaust,
    ->  case when s.amount > 0 and s.amount <= s.crs and s.crs > 0 then 'Fully paid'
    ->  when s.amount > 0 and s.amount > s.crs and s.crs > 0 then concat('Part paid -' ,s.crs)
    ->  else ''
    ->  end msg
    -> from
    -> (
    -> select t1.*,
    ->  if(t1.userid <> @p ,
    ->   @crs:=(select sum(t2.amount)  * - 1 from t t2 where t2.userid = t1.userid and t2.amount < 0)
    ->   ,@crs:=@crs)  crs,
    ->   if(t1.amount < 0 ,@crs:=@crs,if (t1.amount > @crs , @crs:=0,@crs:=@crs - t1.amount)) exhaust,
    ->   @p:=t1.userid p
    ->
    -> from  (select @p:=0,@crs:=0) p ,t t1
    -> order by t1.userid, t1.dt
    -> ) s
    -> ;
+--------+------------+--------+------+---------+--------------+
| userid | dt         | amount | crs  | exhaust | msg          |
+--------+------------+--------+------+---------+--------------+
|    123 | 2017-01-01 |      5 | 2    | 0       | Part paid -2 |
|    123 | 2017-01-03 |      2 | 0    | 0       |              |
|    123 | 2017-01-05 |     -2 | 0    | 0       |              |
|    124 | 2017-01-04 |      2 | 0    | 0       |              |
|    124 | 2017-01-04 |      3 | 0    | 0       |              |
|    125 | 2017-01-01 |      5 | 6    | 1       | Fully paid   |
|    125 | 2017-01-03 |      2 | 1    | 0       | Part paid -1 |
|    125 | 2017-01-05 |     -6 | 0    | 0       |              |
|    126 | 2017-01-01 |      5 | 20   | 15      | Fully paid   |
|    126 | 2017-01-02 |    -10 | 15   | 15      |              |
|    126 | 2017-01-03 |      2 | 15   | 13      | Fully paid   |
|    126 | 2017-01-05 |    -10 | 13   | 13      |              |
|    126 | 2017-01-06 |     13 | 13   | 0       | Fully paid   |
+--------+------------+--------+------+---------+--------------+
13 rows in set (0.03 sec)

注意:- 我还没有完全测试过!!

关于mysql - 在 mysql 或更好的 algothrim 中将每笔交易的借方与贷方相匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42245002/

相关文章:

mysql - MySQL NOW() 的性能

mysql - WHERE 子句为空?不明白

PHP 数据形成与具有某些现有值的数组

jquery - SQL数据库: Update Table for

mysql - 编写 mysql 查询的想法

mysql - 如何根据依赖的两列中的条件过滤记录

algorithm - 由 Mashery 实现的 API 签名认证是如何工作的?

javascript - 比较javascript中的树数据

sql - 模式 : two-way relationships? 哪个表/实体应该拥有 'preference'?

c# - 在 C# 中是否有更好的方法将 DateTime 舍入到最接近的 5 秒?