前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SQL 累计求和

SQL 累计求和

作者头像
白日梦想家
发布2020-07-17 14:17:50
2.3K0
发布2020-07-17 14:17:50
举报
文章被收录于专栏:SQL实现SQL实现

今天看到有群友在群里提了这个问题,问题描述见下图。这种需求在做报表统计时经常会遇到,会的人觉得不难,没有接触过可能会被困住,所以我把它拿出来和大家分享。

图中已把问题描述清楚,再结合数据看就更清晰了。用算法来描述就是:给定一张表(假设表名叫作 t),t 表有字段(oid,period,amount,balance),对同一时期(period 字段的值相等)的金额(amount)按 oid 的顺序做累加求和操作,累加的结果放到 balance 字段。

结合数据来看,在原始数据中,当 oid = 1 时,amount = 3500.00,由于此时只有一条记录,所以 balance = 3500.00 ;当 oid = 2 时,amount = 5100.00balance = 3500.00 + 5100.00 = 8600.00;同理,当 oid = 3 时,balance = 3500.00 + 5100.00 + 10000.00 = 18600.00

我们可通过自关联来实现累计求和的结果,关联的条件这么写 t as t1 INNER JOIN t as t2 ON t2.period = t1.period AND t2.oid <= t1.oid。其中,t1 是主表,用来限定 t2 可以累加的数据的范围。比如,当 t1.oid = 5 时,t2.oid 只能是(4,5),对应的 balance 的计算过程就是 2560.00(t2.oid = 4 时的 amount) + 4700.00(t2.oid = 5 时的 amount)

完整的 SQL 就可以这么写:

代码语言:javascript
复制
WITH t AS 
(SELECT 
  1 AS oid,
  2009 AS period,
  3500.00 AS amount,
  0.00 AS balance 
UNION
SELECT 
  2 AS oid,
  2009 AS period,
  5100.00 AS amount,
  0.00 AS balance 
UNION
SELECT 
  3 AS oid,
  2009 AS period,
  10000.00 AS amount,
  0.00 AS balance 
UNION
SELECT 
  4 AS oid,
  2010 AS period,
  2560.00 AS amount,
  0.00 AS balance 
UNION
SELECT 
  5 AS oid,
  2010 AS period,
  4700.00 AS amount,
  0.00 AS balance) 

# 上面的是造数据的SQL,下面这段才是核心实现
SELECT 
  t1.oid,
  t1.period,
  t1.amount,
  SUM(t2.amount) AS balance 
FROM
  t AS t1 
  LEFT JOIN t AS t2 
    ON t2.period = t1.period 
    AND t2.oid <= t1.oid 
GROUP BY t1.oid,
  t1.period,
  t1.amount ;

看不惯自连接的写法可以换成标量子查询:

代码语言:javascript
复制
SELECT 
  oid,
  period,
  amount,
  (SELECT 
    SUM(amount) 
  FROM
    t 
  WHERE period = t1.period 
    AND oid <= t1.oid) AS balance 
FROM
  t AS t1 

如果你的 MySQL 环境是 8.0 及其以上,可以尝试使用窗口函数。

代码语言:javascript
复制
SELECT 
  oid,
  period,
  amount,
    SUM(amount) over (PARTITION BY period 
  ORDER BY oid) AS balance 
  FROM
    t 

实现累计求和差不多就是这些写法。如果你有不同的实现方式,欢迎在评论区留言,和大家分享你的思路。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SQL实现 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档