多迭代自连接表/文件问题 求Python/SQL/Informatica解决方案
解决方案
Python 实现
核心思路是先构建NEW_ID到OLD_ID的映射字典,再对每个NEW_ID循环追溯完整链路,直到OLD_ID不在映射中为止。
代码示例
import pandas as pd # 读取原始CSV文件 df = pd.read_csv("your_source_file.csv", encoding="utf-8") # 构建NEW_ID到OLD_ID的映射(若存在重复NEW_ID,需先去重或处理冲突) id_mapping = df.set_index("NEW_ID")["OLD_ID"].to_dict() def build_full_chain(start_id): chain = [str(start_id)] current_id = start_id while current_id in id_mapping: next_id = id_mapping[current_id] chain.append(str(next_id)) current_id = next_id # 预防数据中的循环引用,避免无限循环 if len(chain) > len(id_mapping) + 1: break return "--".join(chain) # 生成每个NEW_ID的完整链路 df["FULL_ID_CHAIN"] = df["NEW_ID"].apply(build_full_chain) # 保存结果到新CSV df.to_csv("final_result.csv", encoding="utf-8", quoting=1)
原代码错误说明
你之前的代码错误在于merge时传入了row[0]、row[1](行的具体数值)作为连接键,但merge需要传入列名。同时循环读写文件的逻辑完全偏离需求,导致触发KeyError。
SQL 实现(支持递归CTE的数据库)
针对MySQL 8.0+/PostgreSQL/SQL Server等支持递归CTE的数据库,可直接通过递归查询遍历完整链路:
代码示例
WITH RECURSIVE id_chain AS ( -- 基础查询:初始化每个NEW_ID的初始链路 SELECT NEW_ID, OLD_ID, CAST(NEW_ID AS VARCHAR(255)) AS FULL_CHAIN FROM your_csv_table UNION ALL -- 递归查询:拼接下一层OLD_ID到链路中 SELECT ic.NEW_ID, t.OLD_ID, CONCAT(ic.FULL_CHAIN, '--', t.NEW_ID) AS FULL_CHAIN FROM id_chain ic JOIN your_csv_table t ON ic.OLD_ID = t.NEW_ID ) -- 取每个NEW_ID的最终完整链路 SELECT NEW_ID, MAX(FULL_CHAIN) AS FULL_CHAIN, OLD_ID FROM id_chain GROUP BY NEW_ID, OLD_ID;
说明
递归CTE会自动迭代关联,直到没有匹配的OLD_ID存在于NEW_ID中为止。若使用不支持递归CTE的数据库(如MySQL 5.x),则需通过存储过程循环处理,但效率较低。
Informatica 实现
方案思路
- 构建Lookup映射:用Lookup转换将NEW_ID作为键,OLD_ID作为返回值,建立ID映射关系。
- 循环迭代链路:使用Loop工作流+Sequence Generator,或在Expression转换中通过递归逻辑,不断将匹配到的OLD_ID追加到链路中。
- 终止条件:当Lookup返回NULL(即当前链路的最后一个ID不在NEW_ID中),或达到预设循环次数上限时,终止迭代。
具体步骤
- 从CSV源读取数据,传入Expression转换。
- 在Expression中定义变量存储当前链路,初始值为NEW_ID。
- 调用Lookup转换查询当前链路最后一个ID对应的OLD_ID,若存在则追加到链路,重复此过程。
- 将最终生成的完整链路写入目标文件或数据库表。
内容的提问来源于stack exchange,提问作者Mr.Sappeswaran
相关产品推荐
相关产品推荐

