mysql - 获取最后的余额符号变化(Mysql

标签 mysql sql

我有一个交易表,记录了客户余额中添加减去的每笔金额,以及新余额:

+----+------------+------------+--------+---------+
| id | customerId | timestamp  | amount | balance |
+----+------------+------------+--------+---------+
|  1 |          1 | 1000000001 |     10 |      10 |
|  2 |          1 | 1000000002 |    -20 |     -10 |
|  3 |          1 | 1000000003 |    -10 |     -20 |
|  4 |          2 | 1000000004 |     -5 |      -5 |
|  5 |          2 | 1000000005 |     -5 |     -10 |
|  6 |          2 | 1000000006 |     10 |       0 |
|  7 |          3 | 1000000007 |     -5 |      -5 |
|  8 |          3 | 1000000008 |     10 |       5 |
|  9 |          3 | 1000000009 |     10 |      15 |
| 10 |          4 | 1000000010 |      5 |       5 |
+----+------------+------------+--------+---------+

客户表存储当前余额,如下所示:

+----+---------+
| id | balance |
+----+---------+
|  1 |     -20 |
|  2 |       0 |
|  3 |      15 |
|  4 |       5 |
+----+---------+

我想添加一个 balanceSignSince 列,该列将存储余额符号上次更改的时间戳。在之间转换都算作余额变化。

更新后,根据上述数据,Customer 表应包含:

+----+---------+------------------+
| id | balance | balanceSignSince |
+----+---------+------------------+
|  1 |     -20 |       1000000002 |
|  2 |       0 |       1000000006 |
|  3 |      15 |       1000000008 |
|  4 |       5 |       1000000010 |
+----+---------+------------------+

如何编写一个 SQL 查询,根据事务表更新每个客户上次余额符号更改的时间?

我怀疑如果没有相当复杂的存储过程我就无法做到这一点,但我很好奇是否会出现任何聪明的想法。

最佳答案

这使用模拟的rank()函数。

select customerId, min(tstamp) from
(
select tstamp,
       if (@cust = customerId and sign(@bal) = sign(balance), @rn := @rn,
           if (@cust = customerId and sign(@bal) <> sign(balance), @rn := @rn + 1, @rn := 0)) as rn,
       @cust := customerId as customerId, @bal := balance as balance
from
      (select @rn := 0) x,
      (select id, @cust := customerId as customerId, tstamp, amount, @bal := balance as balance 
       from trans order by customerId, tstamp desc) y
) z
where rn = 0
group by customerId;

检查一下:http://rextester.com/XJVKK61181

此脚本返回一个如下表:

+------------+----+------------+---------+
| tstamp     | rn | customerId | balance |
+------------+----+------------+---------+
| 1000000003 | 0  | 1          | -20     |
| 1000000002 | 0  | 1          | -10     |
| 1000000001 | 1  | 1          | 10      |
| 1000000006 | 0  | 2          | 0       |
| 1000000005 | 2  | 2          | -10     |
| 1000000004 | 2  | 2          | -5      |
| 1000000009 | 0  | 3          | 15      |
| 1000000008 | 2  | 3          | 5       |
| 1000000007 | 3  | 3          | -5      |
| 1000000010 | 0  | 4          | 5       |
+------------+----+------------+---------+

然后选择 rn = 0 的文件的最小值(时间戳):

+------------+-------------+
| customerId | min(tstamp) |
+------------+-------------+
| 1          | 1000000002  |
+------------+-------------+
| 2          | 1000000006  |
+------------+-------------+
| 3          | 1000000009  |
+------------+-------------+
| 4          | 1000000010  |
+------------+-------------+

关于mysql - 获取最后的余额符号变化(Mysql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42054923/

相关文章:

php - Mysql 将多个插入语句转换为一个

java - 更新表时"Parameter index out of range (3 > number of parameters, which is 2)."

mysql语句(SELECT)基于现在的日期

sql - 你能阻止在 postgresql 中的 after 触发器中插入吗?

mysql - 在一个事件调度程序中更新和删除

mysql - SQL查询相关

php - 计算分数/排名系统的分位数 (PHP/MySQL)

php - 精确匹配SQL

mysql - 从 MySQL 中的一个表或另一个表中进行条件选择

mysql - 触发器语句中的语法错误