你是否遇到过这样的场景:数据库中数据是一行一个记录存放的,但是需求要:一行代表一个完整对象。这种行列转换的需求在数据分析中无处不在,今天一起来看看这个问题。一、行列转换重要性
人事部门:数据库每个员工有多条培训记录,但是领导想要一张表,每个员工一行,培训成绩的汇总表。销售部门:原始数据是按照天记录的销售额,月报需要按照产品横向展示出每月总的销售额。财务部门:科目余额是纵向存储的,但是资产负债表需要横向对比数据。这些都是行列转转换的实际工作需求,也是通过行列转换技巧能处理的问题:让数据按照需要的格式,而不是被数据库存储格式限制。
二、行转列:把"竖着看"变成"横着看"
姓名 | 科目 | 分数张三 | 数学 | 90张三 | 英语 | 85李四 | 数学 | 95李四 | 英语 | 80
姓名 | 数学 | 英语张三 | 90 | 85李四 | 95 | 80
SELECT name AS 姓名, MAX(CASE WHEN subject = '数学' THEN score END) AS 数学, MAX(CASE WHEN subject = '英语' THEN score END) AS 英语, MAX(CASE WHEN subject = '语文' THEN score END) AS 语文FROM student_scoresGROUP BY name;
聚合函数(max/sum):确保每个分组只返回一行为什么用max: 因为每个学生学科只有一个分数,max是取唯一值方法2:优雅写法-PIVOT(sqlserver)SELECT *FROM student_scoresPIVOT ( MAX(score) FOR subject IN ('数学' AS math_score, '英语' AS english_score) );
关键点:把subject字段的不同值(数学、英语)变成新的列名,把对应的score值填进去。
三、列转行:把"横着看"变回"竖着看"
产品 | Q1销售额 | Q2销售额 | Q3销售额手机 | 1000 | 1200 | 1500电脑 | 2000 | 1800 | 2200
产品 | 季度 | 销售额手机 | Q1 | 1000手机 | Q2 | 1200手机 | Q3 | 1500电脑 | Q1 | 2000电脑 | Q2 | 1800电脑 | Q3 | 2200
SELECT product AS 产品, 'Q1' AS 季度, Q1销售额 AS 销售额 FROM salesUNION ALLSELECT product AS 产品, 'Q2' AS 季度, Q2销售额 AS 销售额 FROM salesUNION ALLSELECT product AS 产品, 'Q3' AS 季度, Q3销售额 AS 销售额 FROM salesORDER BY 产品, 季度;
SELECT 产品, 季度, 销售额FROM salesUNPIVOT ( 销售额 FOR 季度 IN (Q1销售额, Q2销售额, Q3销售额)) AS unpvt;
关键点:把多个列(Q1销售额、Q2销售额...)变成多行,每行包含原列名和值。
四、实战经验:避免常见的坑
SELECT name, MAX(CASE WHEN subject = '数学' THEN score END) AS 数学 FROM student_scoresGROUP BY name;
SELECT name, COALESCE(MAX(CASE WHEN subject = '数学' THEN score END), 0) AS 数学 FROM student_scoresGROUP BY name;
SELECT user_id, MAX(CASE WHEN action = 'login' THEN 1 ELSE 0 END) AS has_login, MAX(CASE WHEN action = 'purchase' THEN 1 ELSE 0 END) AS has_purchaseFROM user_actionsGROUP BY user_id;
SELECT user_id, MAX(CASE WHEN action = 'login' THEN 1 ELSE 0 END) AS has_login, MAX(CASE WHEN action = 'purchase' THEN 1 ELSE 0 END) AS has_purchaseFROM user_actionsWHERE action IN ('login', 'purchase') GROUP BY user_id;
CREATE INDEX idx_user_action ON user_actions(user_id, action);
五、进阶技巧:多级行列转换
产品 | 月份 | 销售额手机 | 1月 | 1000手机 | 2月 | 1200电脑 | 1月 | 2000电脑 | 2月 | 1800
产品 | 1月销售额 | 2月销售额 | 同比增长手机 | 1000 | 1200 | 20%电脑 | 2000 | 1800 | -10%
SELECT product AS 产品, SUM(CASE WHEN month = '1月' THEN amount END) AS "1月销售额", SUM(CASE WHEN month = '2月' THEN amount END) AS "2月销售额", ROUND( 100.0 * (SUM(CASE WHEN month = '2月' THEN amount END) - SUM(CASE WHEN month = '1月' THEN amount END)) / NULLIF(SUM(CASE WHEN month = '1月' THEN amount END), 0), 2 ) || '%' AS 环比增长FROM salesGROUP BY product;
六、工具选择
| | | |
| case when+聚合 | | |
| | | |
| EXPLODE(LATERAL VIEW) | | |
七、总结
行列转换就像数据世界的"乾坤大挪移",掌握了它,你就掌握了让数据"听话"的能力。
阅读原文:原文链接
该文章在 2026/1/22 13:35:19 编辑过