如何从分存列名与数据的两个CSV生成目标宽表,支持SQL或Python实现
实现方案
以下提供Python和MySQL两种实现方式,均无需手动指定目标列名,可适配任意数量的fields取值。
Python 实现
基于pandas完成表关联和动态转置,代码如下:
import pandas as pd # 读取两个源CSV文件,替换为你本地的文件路径 spend_df = pd.read_csv("消费数据表.csv") mapping_df = pd.read_csv("字段映射表.csv") # 关联两张表,匹配每个消费记录对应的目标列名 merged_df = spend_df.merge( mapping_df, left_on="unique_ref", right_on="id", how="left" ) # 为每个目标列下的消费记录生成行号,避免转置时多笔消费被聚合 merged_df["row_idx"] = merged_df.groupby("fields").cumcount() # 动态转置生成宽表,自动识别所有fields作为列名 result_df = merged_df.pivot( index="row_idx", columns="fields", values="money_spent" ).reset_index(drop=True) # 导出结果CSV,utf-8-sig编码避免中文乱码 result_df.to_csv("消费数据宽表.csv", index=False, encoding="utf-8-sig")
注意事项
- 需提前安装pandas依赖,执行命令:
pip install pandas - 若不同fields对应的消费记录数不一致,缺值位置会自动填充NaN,可根据业务需要调用
fillna方法补充默认值
SQL 实现(MySQL 8.0+)
基于动态SQL自动生成转置逻辑,无需手动枚举列名:
-- 调整group_concat长度限制,避免列数过多时SQL被截断 SET group_concat_max_len = 1024000; -- 动态生成所有列的转置逻辑 SET @dynamic_sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'MAX(CASE WHEN fields = ''', fields, ''' THEN money_spent END) AS `', fields, '`' ) ) INTO @dynamic_sql FROM ( SELECT s.*, m.fields FROM 消费数据表 s LEFT JOIN 字段映射表 m ON s.unique_ref = m.id ) t; -- 拼接完整查询SQL,按行号分组保留多笔消费记录 SET @final_sql = CONCAT(' SELECT ', @dynamic_sql, ' FROM ( SELECT t.*, ROW_NUMBER() OVER(PARTITION BY fields ORDER BY t.id) AS row_num FROM ( SELECT s.id, s.money_spent, m.fields FROM 消费数据表 s LEFT JOIN 字段映射表 m ON s.unique_ref = m.id ) t ) t2 GROUP BY row_num '); -- 执行SQL得到结果 PREPARE stmt FROM @final_sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
注意事项
- 执行后得到的结果集直接导出为CSV即可
- 如果使用MySQL 5.x版本,可替换窗口函数为用户变量的方式生成行号
内容的提问来源于stack exchange,提问作者Abhi0908
相关产品推荐
相关产品推荐

