SQL 计算账户余额

Wesley13
• 阅读 429

有一张简单的账户表 t_account,它记录了每次支出(或收入)的金额,只是缺了余额字段,我们需要在每笔账单后面计算出当时的账户余额。 t_account 的部分数据:

    id  op      amount  
------  ------  --------
     1  in          1000
     2  exp          124
     3  exp           68
     4  exp          256
     5  in            88
     6  in           200
     7  exp           11
     8  exp          404

其中,id 越大表示这条记录产生的时间越近,op 字段是操作类型,‘in’ 表示收入,‘exp’ 表示支出,amount 是每次操作的金额。

具体来说,当 id = 1 时,账户上增加了 1000,此时余额是 1000;

当 id = 2 时,账户减去了 124,此时余额是 1000 - 124 = 876;

当 id = 3 时,账户又减去了 68,此时余额是 1000 - 124 - 68 = 808;

直到 id = 5,账户上才又有了一笔收入,此时余额是 1000 - 124 - 68 - 256 + 88 = 640 。

最终算到 id = 8 时,账户的余额是 425 。

实际上,当 id = x 时,它余额就是将 id 小于等于 x 的所有记录的 amount 累加,如果遇到 op 的类型是 ‘exp’ 的记录,则相应的加法操作变成减法。

话不多说,直接上 SQL 。

SELECT 
  *,
  (SELECT 
    SUM(IF(op = 'exp', - 1 * amount, amount)) 
  FROM
    t_account b 
  WHERE b.id <= a.id) AS balance 
FROM
  t_account a

结果呈现 >>>

    id  op      amount  balance  
------  ------  ------  ---------
     1  in        1000  1000     
     2  exp        124  876      
     3  exp         68  808      
     4  exp        256  552      
     5  in          88  640      
     6  in         200  840      
     7  exp         11  829      
     8  exp        404  425      

如果用窗口函数,那累加的写法会更简单些。

SELECT 
  *,
  SUM(IF(op = 'exp', - 1 * amount, amount)) 
  OVER (ORDER BY id) AS balance 
FROM
  t_account a 

本文分享自微信公众号 - SQL实现(gh_684ee9235a26)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
分布式事务解决方案
一、什么是分布式事务在早期的单体架构时期,所有的数据操作都在同一个数据库里面进行,比如:A给B转100块钱,A的账户余额100,B的账户余额100,这两个操作放在同一个事务里面即可,由数据库来保证事务的原子性、一致性、持久性、隔离性。但是
执键写春秋 执键写春秋
3年前
Java多线程同步示例(银行卡存取款)
Bank类,定义账号、账号余额属性,定义存款方法与取款方法并上同步packageperson.xsc.practice;importjava.util.Scanner;publicclassBankprivateStringaccount;//账号privateintbalance;//账户余额publicBank(Strin
AWS国庆双重礼,仅限7天
自2021年10月1日00:00起至2021年10月7日24:00,新注册并激活(需全部完成账号注册的五个步骤,否则账号状态并未激活)AWS海外区域账户,填写页面下方表单,即可申领价值$200美元的AWS海外区域账户服务抵扣券直充到您的账户,用以抵扣服务消费,助您轻松体验多个云迁移应用场景。同时,您还可获赠AWS精美祥云纪念T恤一件。,仅限7天$20
AWS国庆双重礼,仅限7天
自2021年10月1日00:00起至2021年10月7日24:00,新注册并激活(需全部完成账号注册的五个步骤,否则账号状态并未激活)AWS海外区域账户,填写页面下方表单,即可申领价值$200美元的AWS海外区域账户服务抵扣券直充到您的账户,用以抵扣服务消费,助您轻松体验多个云迁移应用场景。同时,您还可获赠AWS精美祥云纪念T恤一件。,仅限7天$20
国庆假期玩不停双重好礼放肆领
自2021年10月1日00:00起至2021年10月7日24:00,新注册并激活(需全部完成账号注册的五个步骤,否则账号状态并未激活)AWS海外区域账户,填写页面下方表单,即可申领价值$200美元的AWS海外区域账户服务抵扣券直充到您的账户,用以抵扣服务消费,助您轻松体验多个云迁移应用场景。同时,您还可获赠AWS精美祥云纪念T恤一件。AWS国庆T恤
Wesley13 Wesley13
3年前
MySQL 可重复读,差点就让我背上了一个 P0 事故
P0事故:余额多扣!这是一个真实的生产事件,事件起因如下:现有一个交易系统,每次产生交易都会更新相应账户的余额,出账扣减余额,入账增加余额。为了保证资金安全,余额发生扣减时,需要比较现有余额与扣减金额大小,若扣减金额大于现有余额,扣减余额不足,扣减失败。账户表(省去其他字段)结构如下:CREATE TAB
Wesley13 Wesley13
3年前
mq要如何处理消息丢失、重复消费?
如果要你实现一个支付宝向余额宝转账的功能,比如:账户a从支付宝转出5000余额宝转入5000,该怎么做呢?可能有些人会说,这还不简单,直接上图!(https://oscimg.oschina.net/oscnet/7d47d132357446109035157b25361ec7.png)支付宝先给账户a减5000,调用余额
高并发下丢失更新的解决方案
作者:谢益培1背景关键词:并发、丢失更新预收款账户表上有个累计抵扣金额的字段,该字段的含义是统计商家预收款账户上累计用于抵扣结算成功的金额数。更新时机是,账单结算完成时,更新累计抵扣金额累计抵扣金额账单金额。2问
京东云开发者 京东云开发者
2星期前
加锁失效,非锁之过,加之错也
作者:京东零售邢成引言多个进程或线程同时(或着说在同一段时间内)访问同一资源会产生并发问题。银行两操作员同时操作同一账户就是典型的例子。比如A、B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户减去50元,A先提交