Exasol SQL实现逗号分隔列转行并解决多用户重复问题
问题根源
多用户场景下出现重复行的核心原因是CONNECT BY子句未限制递归范围,仅判断了拆分的元素非空,导致递归逻辑跨不同用户的源行生成笛卡尔积,产生大量重复数据。
修正后的SQL
SELECT u.master_user_id , u.user_id , SUBSTR(regexp_substr(u.CONS_DATE_HIST, '[^,]+', 1, level), 1, 8) as date_id , CASE WHEN LOWER(trim(regexp_substr(u.CONS_RULES_HIST, '[^,]+', 1, level))) = 'init' THEN 'init' ELSE SUBSTR(trim(regexp_substr(u.CONS_RULES_HIST, '[^,]+', 1, level)), 6) END AS rule_nbr, level lvl FROM ( SELECT client_id, master_user_id, user_id, CONS_DATE_HIST, CONS_RULES_HIST FROM ECOMBI_CL_0001100.users WHERE cast(load_date as date) > current_date - 4 -- 多用户查询时可放开此处的user_id范围限制 -- and user_id in (38043958 ) ) u connect by -- 限制递归仅在同一用户行内执行,避免跨行生成笛卡尔积 PRIOR u.user_id = u.user_id -- 避免递归循环报错 AND PRIOR SYS_GUID() IS NOT NULL -- 原有的拆分终止条件,调整为非空判断覆盖更多异常场景 AND regexp_substr(u.CONS_DATE_HIST, '[^,]+', 1, level) IS NOT NULL AND regexp_substr(u.CONS_RULES_HIST, '[^,]+', 1, level) IS NOT NULL order by 2,4
修改点说明
- 新增
PRIOR u.user_id = u.user_id:强制递归层级仅在同一个用户的源行内迭代,不会和其他用户的行交叉生成冗余结果 - 新增
PRIOR SYS_GUID() IS NOT NULL:规避Exasol中递归时的循环检测报错,是该场景下的标准兼容写法 - 调整终止条件:将原来的
<>'null'改为IS NOT NULL,覆盖空值、空字符串等异常场景,逻辑更严谨
补充:如果你的表中
user_id存在重复值,可将PRIOR u.user_id = u.user_id替换为PRIOR ROWID = ROWID,基于物理行唯一标识限制递归范围,兼容性更强。
内容的提问来源于stack exchange,提问作者user12063090
相关产品推荐
相关产品推荐

