3

假设一个时间序列,其中每个时间点都有一个值。我必须通过计算当前值 + 前一个值的总和来计算连续总和。然而,棘手的部分是,总和应该有上限,因此不能超过某个值。

示例:总和上限为 +2。

+-----+---------+------------+
| row | measure | capped sum |
+-----+---------+------------+
|   1 |       1 |          1 |
|   2 |       3 |          2 |
|   3 |       4 |          2 |
|   4 |      -2 |          0 |
|   5 |       1 |          1 |
+-----+---------+------------+

例如,第 4 行的“上限总和”是使用前一行“2”中的“上限总和”并加上当前值来计算的。由于结果是 < 2,我们可以按原样取值。

问题是,使用 HANA,我不能在“上限总和”字段上使用 LAG/Window 函数。它会给我一个“未知列”错误。

任何想法如何在不使用 for 循环的情况下在 SQL/HANA SQL 脚本中解决这个问题(这会很慢)?

4

2 回答 2

1

此解决方案使用 HANA 不支持的递归 cte(根据 OP)。发布与支持它的数据库一起使用的解决方案。

WITH ROWNUMS AS
 (SELECT T.*,
         ROW_NUMBER() OVER(ORDER BY ROW) AS RNUM
  FROM T) 
,RCTE AS
 (SELECT ROW,
         RNUM,
         MEASURE,
         MEASURE AS CAPPED_SUM
  FROM ROWNUMS
  WHERE RNUM=1
   UNION ALL
   SELECT RN.ROW,
          RN.RNUM,
          RN.MEASURE,
          CASE
              WHEN R.CAPPED_SUM+RN.MEASURE>=2 THEN 2
              ELSE R.CAPPED_SUM+RN.MEASURE
          END
   FROM ROWNUMS RN
   JOIN RCTE R ON R.RNUM=RN.RNUM-1 )
SELECT ROW,
       MEASURE,
       CAPPED_SUM
FROM RCTE

Sample Demo

于 2017-02-01T21:57:42.397 回答
1

此脚本首先创建运行总和的列。然后它使用该列创建一个“超额”列,即运行总和超过上限值的累积值。然后它减去超额,以便在适当的情况下给出小于 2 的值。

DECLARE @capped_value INT = 2
;WITH CTE AS
(SELECT rowID,measure,
    running_total = SUM(measure) OVER 
    (ORDER BY rowID ROWS UNBOUNDED PRECEDING)
FROM dbo.test_capped_sum)
,
CTE2 AS
(SELECT *,
    overage_total = MAX(CTE.running_total) 
    OVER (ORDER BY rowID ROWS UNBOUNDED PRECEDING) - @capped_value
FROM CTE)

SELECT rowid,measure,
    CASE WHEN CTE2.overage_total > 0
    THEN CTE2.running_total- CTE2.overage_total 
    ELSE CTE2.running_total END
    AS capped_sum FROM CTE2
于 2017-02-01T21:13:22.783 回答