Teradata查询:按指定规则提取客户对应金额值
Teradata 按客户最大rnk规则提取金额的解决方案
问题场景
给定Teradata数据集:
WITH data (cust, amt, rnk) AS ( VALUES('a', 10, 1), ('a', 5, 2), ('a', 15, 3), ('b', 20, 1), ('b', 30, 2), ('c', 3, 1))
需要为每个客户提取金额,规则如下:
- 若客户的最大
rnk值为1,取rnk=1行的amt; - 否则取
rnk=2行的amt。
期望结果:
a,5,2 b,30,2 c,3,1
解决方案
方法一:嵌套子查询+窗口函数
WITH data (cust, amt, rnk) AS ( VALUES('a', 10, 1), ('a', 5, 2), ('a', 15, 3), ('b', 20, 1), ('b', 30, 2), ('c', 3, 1)) SELECT cust, amt, rnk FROM ( SELECT cust, amt, rnk, MAX(rnk) OVER(PARTITION BY cust) AS max_rnk FROM data ) t WHERE (max_rnk = 1 AND rnk = 1) OR (max_rnk > 1 AND rnk = 2);
思路:
- 子查询中通过
MAX(rnk) OVER(PARTITION BY cust)计算每个客户的最大rnk值,生成max_rnk列; - 外层查询根据
max_rnk的值筛选符合规则的行:当max_rnk=1时保留rnk=1的行,当max_rnk>1时保留rnk=2的行。
方法二:QUALIFY子句简化写法(Teradata专属)
Teradata支持QUALIFY子句,可以直接在窗口函数计算后筛选行,无需嵌套子查询:
WITH data (cust, amt, rnk) AS ( VALUES('a', 10, 1), ('a', 5, 2), ('a', 15, 3), ('b', 20, 1), ('b', 30, 2), ('c', 3, 1)) SELECT cust, amt, rnk FROM data QUALIFY CASE WHEN MAX(rnk) OVER(PARTITION BY cust) = 1 THEN rnk = 1 ELSE rnk = 2 END;
思路:QUALIFY子句中用CASE语句判断每个客户的最大rnk值,直接筛选出符合规则的行,语法更简洁。
注意事项
原数据集中VALUES里的客户标识(a/b/c)需要加单引号,否则会被Teradata识别为变量导致语法错误,上述代码已修正该问题。
内容的提问来源于stack exchange,提问作者user3150378
相关产品推荐
相关产品推荐

