Teradata Window/Rolling 多种条件下的求和
Teradata Window/Rolling Sum under Multiple Conditions
我在 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(PARTITION BY ORDER BY RESET WHEN) 我认为方向正确的查询,但似乎无法获得任何想要的结果。
非常感谢任何建议!提前致谢!
我发现 return 这样的结果的唯一方法是利用递归。
如果将数据具体化为 Multiset Volatile Table,并将分区列(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
我在 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(PARTITION BY ORDER BY RESET WHEN) 我认为方向正确的查询,但似乎无法获得任何想要的结果。
非常感谢任何建议!提前致谢!
我发现 return 这样的结果的唯一方法是利用递归。
如果将数据具体化为 Multiset Volatile Table,并将分区列(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