MySQL行转列实现:将参与者答题数据转为宽表格式
行转列实现方案(按参与者聚合答题记录)
嘿,这个行转列的需求在日常数据处理里太普遍了!我给你整理了几种不同数据库下的实现方法,你可以根据自己使用的数据库来选择:
通用方案(几乎所有数据库支持)
如果你的数据库没有专门的行转列函数,用CASE WHEN配合分组聚合是最稳妥的方式,适合MySQL、SQLite这类数据库。假设你的表名为survey_responses,且固定有5个问题(比如Q1到Q5),代码如下:
SELECT participant_id, -- 每个问题对应一列,用MAX/MIN聚合取唯一的answer值 MAX(CASE WHEN question = 'Q1' THEN answer END) AS Q1, MAX(CASE WHEN question = 'Q2' THEN answer END) AS Q2, MAX(CASE WHEN question = 'Q3' THEN answer END) AS Q3, MAX(CASE WHEN question = 'Q4' THEN answer END) AS Q4, MAX(CASE WHEN question = 'Q5' THEN answer END) AS Q5 FROM survey_responses GROUP BY participant_id;
说明:因为每个参与者每个问题只有一条记录,所以用MAX或MIN都能得到正确的answer,本质是把多行的结果合并到一行的对应列中。
专用PIVOT函数方案(SQL Server、Oracle支持)
如果用的是SQL Server或Oracle这类支持PIVOT语法的数据库,可以用更简洁的写法:
SQL Server版本
SELECT participant_id, Q1, Q2, Q3, Q4, Q5 FROM ( -- 先获取源数据 SELECT participant_id, question, answer FROM survey_responses ) AS source_data PIVOT ( -- 聚合函数,同样因为单条记录,MAX/MIN均可 MAX(answer) -- 指定要转成列的字段是question,列出所有目标列名 FOR question IN (Q1, Q2, Q3, Q4, Q5) ) AS pivot_result;
Oracle版本
和SQL Server类似,语法略有差异:
SELECT * FROM ( SELECT participant_id, question, answer FROM survey_responses ) PIVOT ( MAX(answer) FOR question IN ('Q1' AS Q1, 'Q2' AS Q2, 'Q3' AS Q3, 'Q4' AS Q4, 'Q5' AS Q5) );
PostgreSQL专用方案(crosstab函数)
PostgreSQL需要借助tablefunc扩展的crosstab函数来实现:
首先启用扩展(只需执行一次):
CREATE EXTENSION IF NOT EXISTS tablefunc;
然后执行行转列查询:
SELECT * FROM crosstab( -- 源查询必须按participant_id和question排序 'SELECT participant_id, question, answer FROM survey_responses ORDER BY participant_id, question' ) AS result_table(participant_id INT, Q1 TEXT, Q2 TEXT, Q3 TEXT, Q4 TEXT, Q5 TEXT);
注意:需要根据你的实际字段类型调整result_table里的列类型(比如把INT改成VARCHAR,TEXT改成INT等)。
内容的提问来源于stack exchange,提问作者Shamseer Pc
相关产品推荐
相关产品推荐

