如何对含可变列数据的表格执行PIVOT转换以达成指定结果?
实现宽表转窄表(逆透视/Unpivot)的方案
咱先明确一下:你要完成的是**逆透视(Unpivot)**操作——和常见的「行转列」Pivot方向相反,这里是把宽表的多列拆分成多行的窄表。不同SQL数据库有不同的实现方式,下面给你几种实用方案:
1. SQL Server 专用语法(UNPIVOT关键字)
如果用的是SQL Server,直接用内置的UNPIVOT关键字就能快速实现,代码简洁高效:
SELECT rownum, respnum, question, answer FROM YourTableName -- 替换成你的实际表名 UNPIVOT ( answer FOR question IN (q2, q3) -- q2、q3是要转换的列名 ) AS unpvt_result;
解释:
IN (q2, q3)指定要拆分成行的列,这些列名会成为question列的取值answer是用来存储原列值的新列名- 执行后会直接输出你想要的目标表格结构
2. 通用SQL写法(兼容MySQL、PostgreSQL、SQLite等)
如果你的数据库不支持UNPIVOT(比如MySQL、PostgreSQL早期版本),可以用UNION ALL手动拼接结果,兼容性拉满:
-- 先取出q2对应的行 SELECT rownum, respnum, 'q2' AS question, q2 AS answer FROM YourTableName UNION ALL -- 再取出q3对应的行 SELECT rownum, respnum, 'q3' AS question, q3 AS answer FROM YourTableName -- 按rownum和question排序,和目标格式对齐 ORDER BY rownum, question;
解释:
- 每个要转换的列对应一个
SELECT语句,手动指定question的固定值(就是原列名) - 用
UNION ALL把多个结果集合并(注意用UNION ALL而非UNION,避免不必要的去重,提升效率) - 最后加
ORDER BY让结果和目标表格的排序一致
扩展提示
如果后续需要转换更多列(比如q4、q5):
- 用
UNPIVOT的话,只需要在IN()里添加对应的列名即可 - 用
UNION ALL的话,新增对应的SELECT块就行
内容的提问来源于stack exchange,提问作者J.Pyz
相关产品推荐
相关产品推荐

