如何将QUESTIONNAIRE表数据转成行插入ANSWER表(Pandas/SQL方法)
宽表转长表实现方案(SQL + Pandas)
一、SQL实现方式
1. 通用UNION ALL写法(兼容所有SQL数据库)
如果数据库不支持专用列转行函数,直接用UNION ALL拼接每个问题列的结果,兼容性拉满:
INSERT INTO ANSWER (QuestionnaireID, QuestionCode, Answer) SELECT QuestionnaireID, 'EXT1' AS QuestionCode, EXT1 AS Answer FROM QUESTIONNAIRE UNION ALL SELECT QuestionnaireID, 'EXT2' AS QuestionCode, EXT2 AS Answer FROM QUESTIONNAIRE -- 依次类推,补充EXT3到EXT50的查询语句 UNION ALL SELECT QuestionnaireID, 'EXT50' AS QuestionCode, EXT50 AS Answer FROM QUESTIONNAIRE;
嫌手动写50行麻烦的话,可以用脚本循环生成这段SQL代码。
2. 专用UNPIVOT写法(适用于SQL Server、Oracle等)
支持UNPIVOT语法的数据库可以用更简洁的方式:
INSERT INTO ANSWER (QuestionnaireID, QuestionCode, Answer) SELECT QuestionnaireID, QuestionCode, Answer FROM QUESTIONNAIRE UNPIVOT ( Answer FOR QuestionCode IN (EXT1, EXT2, ..., EXT50) ) AS unpvt;
把括号里的EXT1, EXT2, ..., EXT50替换成实际的50个问题列名即可。
3. PostgreSQL专属写法(LATERAL JOIN + UNNEST)
PostgreSQL可以用更灵活的数组方式处理:
INSERT INTO ANSWER (QuestionnaireID, QuestionCode, Answer) SELECT q.QuestionnaireID, unnest(array['EXT1','EXT2',...,'EXT50']) AS QuestionCode, unnest(array[EXT1,EXT2,...,EXT50]) AS Answer FROM QUESTIONNAIRE q;
注意两个array内的元素顺序必须严格对应,确保问题编码和答案匹配。
二、Pandas实现方式
用Pandas的melt函数一键完成列转行,步骤如下:
- 读取QUESTIONNAIRE表到DataFrame:
import pandas as pd # 从数据库读取(以SQLAlchemy为例) # from sqlalchemy import create_engine # engine = create_engine('你的数据库连接字符串') # df = pd.read_sql('SELECT * FROM QUESTIONNAIRE', engine) # 从本地文件读取(比如CSV) # df = pd.read_csv('questionnaire_data.csv')
- 执行列转行转换:
long_df = pd.melt( df, id_vars=['QuestionnaireID'], # 保留的主键列 var_name='QuestionCode', # 转换后的问题编码列名 value_name='Answer' # 转换后的答案列名 )
- 将结果写入ANSWER表或导出:
# 写入数据库 # long_df.to_sql('ANSWER', engine, if_exists='append', index=False) # 导出为CSV文件 # long_df.to_csv('answer_data.csv', index=False)
转换完成后long_df会生成50000行数据,完全符合需求。
内容的提问来源于stack exchange,提问作者Saber Alex
相关产品推荐
相关产品推荐

