【问题标题】:Reset Cumulative Sum When Condition is met满足条件时重置累计和
【发布时间】:2020-07-03 02:30:51
【问题描述】:

我有一张这样的桌子

+----+--------+
| ID | Weight |
+----+--------+
|  1 |   8100 |
|  2 |   8235 |
|  3 |   7950 |
|  4 |   8175 |
|  5 |   8185 |
|  6 |   7985 |
|  7 |   8180 |
+----+--------+

我想获取权重的累积和,然后当累积和大于等于 20000 时重置累积和。

+----+--------+----------------+----------------+
| ID | Weight | CumWeightBySum | ResetCumWeight |
+----+--------+----------------+----------------+
|  1 |   8100 |           8100 |           8100 |
|  2 |   8235 |          16335 |          16335 |
|  3 |   7950 |          24285 |          24285 |
|  4 |   8175 |          32460 |           8175 |    <- Reset Cumulative Sum
|  5 |   8185 |          40645 |          16350 |
|  6 |   7985 |          48630 |          24335 |
|  7 |   8180 |          56810 |           8180 |    <- Reset Cumulative Sum
+----+--------+----------------+----------------+

【问题讨论】:

  • 如果ResetCumWeight 意味着每20000 重置一次,那么它的列值不应该是8100,16335,4285,12460,645,8630,16810吗?
  • @DaleK -- 一个有趣的评论 -- 经常与一些简单的东西一起使用,应该不难实现 -- 这显然在 SQL 中实现起来并不简单。但是,我的尝试低于:D
  • @Hogan 问题的难易程度与 OP 是否尝试无关。相关的是OP是否已经成功。否则我们只是一个代码编写服务。

标签: sql-server cumulative-sum


【解决方案1】:

在 sql 中做这样的事情的问题是,由于 sql 在集合中工作,因此解决方案必须是递归的。递归会很慢。如果你在前端实现了这个,你可以使用一个循环,你不需要递归。所以,除非有什么技巧我不知道你真的想在前端这样做。

这和你想要的很接近

SELECT s2.id, s2.weight, 
 -- total, x, z, 
   part, total,
  SUM(s2.weight) OVER (PARTITION BY s2.part ORDER BY s2.id asc) as resetw
FROM (
  SELECT id, weight, 
    total,
    COALESCE(LAG(total) OVER (ORDER BY id asc) ,0) / 20000 as part
  FROM (
    select
      id, weight,
      SUM(weight) OVER (ORDER BY id asc) as total
    from test
   ) s1 
 ) s2

老实说,在前端做这件事要容易得多,在 SQL 中做这件事似乎是白费力气。

如果你想玩,这里是小提琴

http://sqlfiddle.com/#!18/1111a1/28

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多