在 Teradata 中达到阈值后,将一列数字会话化为 30 组

Sessionize a column of numbers into groups of 30 once a threshold is met in Teradata

考虑代表 "time between events":

的列

(5, 40, 3, 6, 0, 9, 0, 4, 5, 18, 2, 4, 3, 2)

我想将这些分组到 30 个桶中,但桶会重置。期望的结果:

(0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2)

这是因为,当我们累计到 30 时,我们 "reset" 并重新开始计数。因此,5 + 40 > 30,我们下降到零并开始累积加法,直到达到 30...(3 + 6 + 0 ...),这发生在我们到达第 10 个元素 == 18.[=42 时=]

这可以通过 Reduce 函数实现(参见 ),但我不知道如何在 Teradata 中实现它?就像我需要能够在同一个调用中引用同一个 OVER(PARTITION BY ...


打破逻辑,下面是 Excel 中的示例:

其中,B2 有公式: =IF(B1<30, B1+A2, A2) 并相应地向下拖动。列 C 然后检查列 B 是否 >=30,列 D 是否是列 B.

的简单累加

我知道在 Teradata 中执行此操作的唯一方法是使用递归 CTE。因为我很懒,让我们将其简化为当 运行 总和大于 2 时要重置。 为此创建并填充一个非常简单的 volatile table:

CREATE VOLATILE TABLE vt1
(
    foo VARCHAR(10)
    , counter INTEGER
    , bar INTEGER
)
ON COMMIT PRESERVE ROWS;

INSERT INTO vt1 VALUES ('a', 1, '1');
INSERT INTO vt1 VALUES ('a', 2, '2');
INSERT INTO vt1 VALUES ('a', 3, '2');
INSERT INTO vt1 VALUES ('a', 4, '4');
INSERT INTO vt1 VALUES ('a', 5, '1');
INSERT INTO vt1 VALUES ('b', 1, '3');
INSERT INTO vt1 VALUES ('b', 2, '1');
INSERT INTO vt1 VALUES ('b', 3, '1');
INSERT INTO vt1 VALUES ('b', 4, '2');

这是实际的 select:

WITH RECURSIVE cte (foo, counter, bar, rsum) AS
(
SELECT
    foo
  , counter
  , bar
  , bar AS rsum
FROM 
    vt1
QUALIFY ROW_NUMBER() OVER (PARTITION BY foo ORDER BY counter) = 1

UNION ALL

SELECT
    t.foo
  , t.counter
  , t.bar
  , CASE WHEN cte.rsum < 3 THEN t.bar + cte.rsum ELSE t.bar END
FROM
    vt1 t JOIN cte ON t.foo = cte.foo AND t.counter = cte.counter + 1
)

SELECT 
    cte.*
  , CASE WHEN rsum < 5 THEN 0 ELSE 1 END AS tester
FROM 
    cte
ORDER BY 
    foo
    , counter
;

最终会给我们:

╔═════╦═════════╦═════╦══════╦════════╗
║ foo ║ counter ║ bar ║ rsum ║ tester ║
╠═════╬═════════╬═════╬══════╬════════╣
║ a   ║       1 ║   1 ║    1 ║      0 ║
║ a   ║       2 ║   2 ║    3 ║      0 ║
║ a   ║       3 ║   2 ║    5 ║      1 ║
║ a   ║       4 ║   4 ║    4 ║      0 ║
║ a   ║       5 ║   1 ║    5 ║      1 ║
║ b   ║       1 ║   3 ║    3 ║      0 ║
║ b   ║       2 ║   1 ║    4 ║      0 ║
║ b   ║       3 ║   1 ║    5 ║      1 ║
║ b   ║       4 ║   2 ║    2 ║      0 ║
╚═════╩═════════╩═════╩══════╩════════╝

case 语句为我们处理重置。

它有点丑,但我从来没能用其他任何方式让它工作。