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

Sql 在Teradata中达到阈值后,将数字列会话化为30组,sql,grouping,sequence,teradata,window-functions,Sql,Grouping,Sequence,Teradata,Window Functions,考虑一个表示事件间隔时间的列: 5,40,3,6,0,9,0,4,5,18,2,4,3,2 我想把它们分成30个桶,但是桶会重置。预期结果: 0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2 这是因为,当我们累积到30时,我们重置并再次开始计数。所以,5+40>30,我们下降到零,开始累计相加,直到达到30…3+6+0…,这发生在我们达到第10个元素==18时 这可以通过Reduce函数实现,但我不知道如何在Teradata中实现它?这就像我需要能够参考相同的超额支付。。。在同一个

考虑一个表示事件间隔时间的列:

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

我想把它们分成30个桶,但是桶会重置。预期结果:

0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2

这是因为,当我们累积到30时,我们重置并再次开始计数。所以,5+40>30,我们下降到零,开始累计相加,直到达到30…3+6+0…,这发生在我们达到第10个元素==18时

这可以通过Reduce函数实现,但我不知道如何在Teradata中实现它?这就像我需要能够参考相同的超额支付。。。在同一个电话里

分解逻辑,下面是Excel中的一个示例:


其中,B2的公式为:=IFB1=30,D列是B列的简单求和。

我知道在Teradata中实现这一点的唯一方法是使用递归CTE。因为我很懒,让我们简化一下,当你的运行总和大于2时,你想重置。 为此创建并填充一个非常简单的volatile表:

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');
以下是实际选择:

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
;
case语句为我们处理重置


这有点难看,但我从来没能以任何其他方式实现这一点。

是否有任何列指定顺序?假设时间间隔已经有序。但事实上,您可以认为会有两个额外的列:cust_id和event_time。所以,一堆超额支付条款将是按事件时间行按客户订单超额支付…@vkp请参阅我的上述评论,以便澄清,并让我知道您是否认为应该将其添加到问题中。是否有任何列对您的结果进行分组?每组的平均/最大行数是多少?每个存储桶的平均行数是多少?您可以执行多个步骤吗?例如,为此过程创建一个易失性表?您可以创建存储过程吗?同意这是一个难看但有用的+1-我不熟悉CTE,所以我明天将使用它,但是,您是否有可能扩展/概括您的示例:通过id字段进行的分区在整个过程中并不完全相同,我不确定我是否理解为什么foo返回1:5;b表示当扩展到大于4的和时,情况是如何变化的?计数器逻辑曾经改变过吗?对不起,结果的粘贴很时髦,现在检查一下。计数器只是partition子句中orderby的一个简单列。可能是约会什么的。我把CTE中的数据也扩展了一点,现在变得更有意义了。非常感谢。我将暂时不回答这个问题,看看是否有其他人可以想出一个替代方法或更简单的方法。创建了一个问题,询问如何从这个输出创建递归视图-我想这是一个单独的问题,但也许你可以帮上忙。再次感谢!
╔═════╦═════════╦═════╦══════╦════════╗
║ 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 ║
╚═════╩═════════╩═════╩══════╩════════╝