总和超出范围,但在其他列值为 1 时重置

Posted

技术标签:

【中文标题】总和超出范围,但在其他列值为 1 时重置【英文标题】:Sum over range but reset when other column value is 1 【发布时间】:2021-03-19 08:24:12 【问题描述】:

所以我有一个帐号和一个读数,我想取其累计总和,但在新的读数周期开始时重置(我想重置运行总和)。

我正在使用一个窗口函数,但是当新的阅读周期存在时,我不知道如何设置它。

数据格式如下:

阅读周期音量值是我想要达到的目标。

目前我已经尝试过SUM(Value) OVER(PARTITION BY ACCOUNT ORDER BY OBS)

读取# = 1时不知道如何重置。

我试过了:

Case 
   when [Reading #] = 1 THEN value 
   ELSE SUM(Value) OVER(PARTITION BY ACCOUNT ORDER BY OBS) 
END AS [Running Total]

【问题讨论】:

请展示您的尝试和预期结果。也请避免使用图像。将示例数据作为格式化文本发布 请同时显示您的预期输出 【参考方案1】:

如果我正确理解问题并且存储在Obs[Reading #] 列中的值没有间隙,则下一个方法是一个选项:

表:

SELECT *
INTO Data
FROM (VALUES
   (1, 1,  1, 5),
   (1, 2,  2, 6),
   (1, 3,  3, 5),
   (1, 4,  4, 6),
   (1, 5,  5, 5),
   (1, 6,  6, 5),
   (1, 7,  1, 5),
   (1, 8,  2, 6),
   (1, 9,  3, 5),
   (1, 10, 4, 6),
   (1, 11, 5, 5),
   (1, 12, 6, 5),
   (2, 1,  1, 7),
   (2, 2,  2, 8),
   (2, 3,  3, 9),
   (2, 4,  4, 10),
   (2, 5,  5, 11),
   (2, 6,  6, 12),
   (2, 7,  1, 7),
   (2, 8,  2, 8),
   (2, 9,  3, 9),
   (2, 10, 4, 10),
   (2, 11, 5, 11),
   (2, 12, 6, 12)
) v (Account, Obs, [Reading #], [Value])

声明:

SELECT
   Account, Obs, [Reading #], [Value],
   SUM([Value]) OVER (PARTITION BY Account, [Group] ORDER BY Account, Obs) AS [Ready Cicle Value]
FROM (
   SELECT 
      *, 
      (Obs - [Reading #]) AS [Group]
   FROM Data
) t

另一个选项(作为更通用的方法)是在 [Reading #] 等于 1 时创建组:

SELECT 
   Account, Obs, [Reading #], [Value],
   SUM([Value]) OVER (PARTITION BY Account, [Group] ORDER BY Obs) AS [Ready Cicle Value]
FROM (
   SELECT *, SUM([Change]) OVER (PARTITION BY Account ORDER BY Obs) AS [Group]
   FROM (
      SELECT *, CASE WHEN [Reading #] = 1 THEN 1 ELSE 0 END AS [Change]
      FROM Data
   ) a
) b  

【讨论】:

【参考方案2】:

帮助我们为您提供帮助。始终包含一组最少的数据和我们需要的代码,我们可以复制和粘贴它们以立即与您在同一页面上,而不会浪费时间和精力,而这些时间和精力最好花在帮助他人上。请注意如何简单地复制和粘贴我们的解决方案并使用它们?它们是完整且独立的。这就是我们希望您提供的。

你很接近。您缺少的部分是您需要某种方法来对读数进行分组,然后您也可以将其包含在分区中。

有多种方法可以为“reading_group”创建新的派生值,以下只是一种方法。

DECLARE @t_customer_readings TABLE
(   account_number  INT,    
    observation     INT,
    reading_number  INT,
    reading_value   INT
)

INSERT INTO @t_customer_readings
VALUES (1, 1 , 1, 3),
       (1, 2 , 2, 6),
       (1, 3 , 3, 9),
       (1, 4 , 4, 5),
       (1, 5 , 5, 5),
       (1, 6 , 6, 8),
       (1, 7 , 1, 1),
       (1, 8 , 2, 4),
       (1, 9 , 3, 7),
       (1, 10, 4, 0),
       (1, 11, 5, 3),
       (1, 12, 6, 6),
       (2, 1 , 1, 9),
       (2, 2 , 2, 2),
       (2, 3 , 3, 5),
       (2, 4 , 4, 8),
       (2, 5 , 5, 1),
       (2, 6 , 6, 4),
       (2, 7 , 1, 7),
       (2, 8 , 2, 0),
       (2, 9 , 3, 3),
       (2, 10, 1, 6), -- note I have split this group into 2 to show that the reading numbers do not need to be sequential.
       (2, 11, 5, 9),
       (2, 12, 6, 2)

SELECT r.*,
 --    reading_group = CASE WHEN r.reading_number = 1 THEN observation ELSE rg.reading_group END,
       ready_cycle_volume = SUM(reading_value) OVER(PARTITION BY account_number, 
                                                                 CASE WHEN r.reading_number = 1 THEN observation 
                                                                      ELSE rg.reading_group 
                                                                  END 
                                                        ORDER BY observation)
  FROM @t_customer_readings r
 CROSS APPLY
       (SELECT reading_group = MAX(observation) -- I picked observation but you could use whatever value you like. we are just creating something we can group on.
          FROM @t_customer_readings
         WHERE account_number = r.account_number
           AND observation < r.observation
           AND reading_number = 1) rg

【讨论】:

以上是关于总和超出范围,但在其他列值为 1 时重置的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 错误 1264:列的值超出范围

列 Oracle 到 MySQL 的值超出范围

std::thread 不是全局变量,但在到达创建它的函数末尾时不会超出范围?

从“未配置分区重置策略的偏移量超出范围”中恢复

如何在路径中获取最后一个文件夹时解决运行时错误9,下标超出范围

Swiftui foreach 索引超出范围 ondelete 问题