Teradata同表多行数字对比:Pull字段赋值SQL问题排查
解决Teradata中根据Codes和Claim_ID赋值Pull字段的问题
嘿,我看了你写的SQL和需求,问题出在代码的逻辑判断和UNION的用法上,咱们一步步来修正。
首先先明确你的需求规则,再拆解问题:
需求规则
- 当
Claim_ID为'Y'时,Pull固定为'Y' - 同一
Member_ID下,Claim_ID='N'的记录:如果其Codes中的所有数字都存在于该用户Claim_ID='Y'的Codes中,Pull为'Y';只要有一个数字不在,Pull为'N'
现有代码的问题
你用OREPLACE来判断包含关系是不靠谱的——逗号分隔的字符串顺序一变就会判断错误(比如B的Codes是35,12,A的是12,23,35,78,OREPLACE就匹配不上),而且无法准确检查所有子代码是否都在父集合里。另外你的UNION逻辑也没处理好,导致结果不符合预期。
正确的解决方案
处理逗号分隔的代码列表,最好的方式是先把字符串拆分成单个代码行,再进行集合对比。Teradata的STRTOK_SPLIT_TO_TABLE函数可以帮我们做这件事,具体SQL如下:
WITH member_y_codes AS ( -- 先获取每个Member_ID下Claim_ID='Y'的所有代码集合 SELECT Member_ID, TRIM(STRTOK(Codes, ',', t.token_num)) AS code FROM DBC.PULL_COMP CROSS JOIN TABLE(STRTOK_SPLIT_TO_TABLE(Member_ID, Codes, ',')) AS t WHERE Claim_ID = 'Y' ), n_claim_check AS ( -- 检查每个Claim_ID='N'的记录,其所有代码是否都在对应Member的Y代码集合中 SELECT b.Member_ID, b.Claim_ID, b.Codes, -- 如果不存在任何不在Y集合中的代码,Pull为Y,否则为N CASE WHEN NOT EXISTS ( SELECT 1 FROM TABLE(STRTOK_SPLIT_TO_TABLE(b.Member_ID, b.Codes, ',')) AS t WHERE TRIM(STRTOK(b.Codes, ',', t.token_num)) NOT IN ( SELECT code FROM member_y_codes a WHERE a.Member_ID = b.Member_ID ) ) THEN 'Y' ELSE 'N' END AS Pull FROM DBC.PULL_COMP b WHERE b.Claim_ID = 'N' ) -- 合并Claim_ID='Y'的记录和检查后的Claim_ID='N'的记录 SELECT Member_ID, Claim_ID, Codes, 'Y' AS Pull FROM DBC.PULL_COMP WHERE Claim_ID = 'Y' UNION ALL SELECT Member_ID, Claim_ID, Codes, Pull FROM n_claim_check ORDER BY Member_ID, Claim_ID DESC; -- 按Member_ID排序,Y记录在前
代码逻辑解释
member_y_codesCTE:把每个Member_ID下Claim_ID='Y'的Codes拆分成单个代码行,方便后续对比。n_claim_checkCTE:对每个Claim_ID='N'的记录,同样拆分Codes为单个代码,用NOT EXISTS检查是否有代码不在该用户的Y代码集合中——如果没有,说明所有代码都在,Pull为Y,否则为N。- 最后合并结果:直接取出所有Y的记录(Pull固定为Y),再合并检查后的N记录,排序后得到最终结果。
用你的测试数据运行这段代码,会得到完全符合预期的结果:
| Member_ID | Claim_ID | Codes | Pull |
|---|---|---|---|
| 123 | Y | 12,23,35,78 | Y |
| 123 | N | 12,35 | Y |
| 123 | N | 23,34 | N |
| 123 | N | 33,34 | N |
内容的提问来源于stack exchange,提问作者priyanka jha
相关产品推荐
相关产品推荐

