You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 06:23:06