多条件下的Teradata窗口/滚动和

时间:2015-08-11 16:04:05

标签: sql sum teradata cumulative-sum

我在Teradata SQL Assistant 14.10中工作并遇到以下问题的问题:

我有一个计算的经过时间列表,我需要创建一个标记何时

的列
  • a)第一次经过时间总和超过20分钟的行
  • b)在此之后每次经过时间总和超过15分钟的行

这里的困难在于,在满足每个条件之后,用于设置标志的滚动总和将需要变为0。请参阅以下结果集,其中FLAG是基于上述条件的所需输出列,以及原因列,解释了为什么要标记它。

RN  REPORT_DT   SEG_CD  NUM_F   T1          T2          ELAPSED_TIME    FLAG    REASON
1   6/22/2015   STATION 881     18:33:00    17:30:00    63              1       63 >= 20 min for first time
2   6/22/2015   STATION 881     18:45:00    18:33:00    12              0       12 < 15
3   6/22/2015   STATION 881     19:00:00    18:45:00    15              1       12 + 15 >= 15
4   6/22/2015   STATION 881     19:15:00    19:00:00    15              1       15 >= 15
5   6/22/2015   STATION 881     19:30:00    19:15:00    15              1       15 >= 15
6   6/22/2015   STATION 881     19:40:00    19:30:00    10              0       10 < 15
7   6/22/2015   STATION 881     19:50:00    19:40:00    10              1       10 + 10 >= 15
8   6/22/2015   STATION 881     20:00:00    19:50:00    10              0       10 < 15
9   6/22/2015   STATION 881     20:10:00    20:00:00    10              1       10 + 10 >= 15

我已经尝试了各种SUM()OVER(按重置顺序排序)我觉得这种查询是正确的方向,但似乎无法得到任何预期的结果。

任何建议都非常感谢!提前谢谢!

1 个答案:

答案 0 :(得分:3)

我发现返回这样的结果的唯一方法是使用递归。

如果您将数据实现为Multiset易失性表,并将分区列(REPORT_DT,SEG_CD,NUM_F)作为主索引,然后开始递归,那么您将获得最快的速度:

WITH RECURSIVE cte AS
(   
SELECT
  RN,
  REPORT_DT,
  SEG_CD,
  NUM_F,
  T1,
  T2,
  ELAPSED_TIME,
  CASE WHEN ELAPSED_TIME >= 20 
       THEN 0 
       ELSE ELAPSED_TIME
  END AS sum_ELAPSED_TIME,
  CASE WHEN sum_ELAPSED_TIME = 0 
       THEN 1 
       ELSE 0
  END AS FLAG
FROM vt
WHERE rn = 1

UNION ALL

SELECT
  vt.RN,
  vt.REPORT_DT,
  vt.SEG_CD,
  vt.NUM_F,
  vt.T1,
  vt.T2,
  vt.ELAPSED_TIME,
  CASE WHEN cte.sum_ELAPSED_TIME + vt.ELAPSED_TIME >= 15 
       THEN 0 
       ELSE cte.sum_ELAPSED_TIME + vt.ELAPSED_TIME 
  END AS new_ELAPSED_TIME,
  CASE WHEN new_ELAPSED_TIME = 0
       THEN 1 
       ELSE 0
  END AS FLAG
FROM vt 
JOIN cte 
  ON vt.REPORT_DT = cte.REPORT_DT
 AND vt.SEG_CD = cte.SEG_CD
 AND vt.NUM_F = cte.NUM_F
 AND vt.rn = cte.rn + 1
) 
SELECT * FROM cte