SQL技术问询:如何将多列合并为多行单列?附转换示例
嘿,这个需求其实是典型的**行转列(Pivot)**操作,不过得先把原表的age和gender字段拆成键值对形式的行记录,再把用户名字转成列来展示对应的值。下面给你两种适配不同数据库的实现方式:
先明确原表结构与数据
首先我们先创建原表并插入示例数据,方便后续测试:
-- 创建原表 CREATE TABLE original_table ( name VARCHAR(50), age INT, gender CHAR(1) ); -- 插入示例数据 INSERT INTO original_table VALUES ('John', 20, 'M'), ('Jill', 21, 'F'), ('Exam', 22, 'M');
方法1:使用PIVOT关键字(适用于SQL Server、PostgreSQL 11+等支持该语法的数据库)
我们先通过UNION ALL把age和gender拆成单独的行,再用PIVOT把用户名字转成列:
SELECT attribute, Exam, Jill, -- 按你需求的列顺序调整,这里对应age行的22、21、20 John FROM ( -- 把age和gender转成键值对形式的行 SELECT name, 'age' AS attribute, CAST(age AS VARCHAR) AS value FROM original_table UNION ALL SELECT name, 'gender' AS attribute, gender AS value FROM original_table ) AS unpivoted_data PIVOT ( MAX(value) FOR name IN (Exam, Jill, John) ) AS pivoted_result;
方法2:条件聚合(通用所有关系型数据库,比如MySQL、SQLite等)
如果你的数据库不支持PIVOT关键字,用CASE WHEN配合聚合函数是最稳妥的通用方案:
SELECT attribute, MAX(CASE WHEN name = 'Exam' THEN value END) AS Exam, MAX(CASE WHEN name = 'Jill' THEN value END) AS Jill, MAX(CASE WHEN name = 'John' THEN value END) AS John FROM ( SELECT name, 'age' AS attribute, CAST(age AS VARCHAR) AS value FROM original_table UNION ALL SELECT name, 'gender' AS attribute, gender AS value FROM original_table ) AS unpivoted_data GROUP BY attribute;
最终结果
执行上面的SQL后,你会得到符合需求的结果:
| attribute | Exam | Jill | John |
|---|---|---|---|
| age | 22 | 21 | 20 |
| gender | M | F | M |
如果需要调整列的顺序,只要修改SELECT语句里的列顺序或者PIVOT/CASE WHEN里的名字顺序就行。
内容的提问来源于stack exchange,提问作者Quan Le Duc Minh
相关产品推荐
相关产品推荐

