当前位置: 首页> 财经> 股票 > 列转行-多列转多行(横表变竖表)

列转行-多列转多行(横表变竖表)

时间:2025/7/13 20:17:33来源:https://blog.csdn.net/thenowaiting/article/details/141942317 浏览次数:0次

一、基础数据

有学生成绩表,包含学生id、语文、数学、英语三科成绩

+-------------+--------+---------+---------+
| student_id  | yuwen  | shuxue  | yingyu  |
+-------------+--------+---------+---------+
| 001         | 89     | 95      | 77      |
| 002         | 92     | 83      | 97      |
| 003         | 81     | 94      | 88      |
+-------------+--------+---------+---------+

二、函数介绍

  • sum
  • case

三、多列转多行(横表变竖表)

原始数据为一张横表,分别有三列成绩列,想要转成竖表,需要转换成三列分别为 学生id、学科、成绩,转换完成之后学生id将不再是主键。

期望结果

+-------------+----------+--------+
| student_id  | subject  | score  |
+-------------+----------+--------+
| 001         | 语文       | 89     |
| 001         | 数学       | 95     |
| 001         | 英语       | 77     |
| 002         | 语文       | 92     |
| 002         | 数学       | 83     |
| 002         | 英语       | 97     |
| 003         | 语文       | 81     |
| 003         | 数学       | 94     |
| 003         | 英语       | 88     |
+-------------+----------+--------+

1.union all 完成数据

使用union all 对不同学科的数据进行组合,得到最终结果。

执行SQL

--语文成绩
select student_id,'语文' as subject,yuwen  as score
from t_student_score_02
union all
--数学成绩
select student_id,'数学' as subject,shuxue as score
from t_student_score_02
union all
--英语成绩
select student_id,'英语' as subject,yingyu as score
from t_student_score_02

执行结果

+-------------+----------+--------+
| student_id  | subject  | score  |
+-------------+----------+--------+
| 001         | 语文       | 89     |
| 002         | 语文       | 92     |
| 003         | 语文       | 81     |
| 001         | 数学       | 95     |
| 002         | 数学       | 83     |
| 003         | 数学       | 94     |
| 001         | 英语       | 77     |
| 002         | 英语       | 97     |
| 003         | 英语       | 88     |
+-------------+----------+--------+

2.数据拼接后炸裂开

2.1拼接数据

使用concat对科目和科目对应的分数进行拼接,然后使用concat_ws把不同科目数据拼接到一起

执行SQL

select student_id,concat_ws(',', concat('语文:', yuwen), concat('数学:', shuxue), concat('英语:', yingyu)) as sub_scores
from t_student_score_02

执行结果

+-------------+--------------------+
| student_id  |     sub_scores     |
+-------------+--------------------+
| 001         | 语文:89,数学:95,英语:77  |
| 002         | 语文:92,数学:83,英语:97  |
| 003         | 语文:81,数学:94,英语:88  |
+-------------+--------------------+
2.2 lateral view explode 将成绩列转行

使用lateral view explode 将成绩列转行,然后使用split将科目和分数分开。
执行SQL

select student_id,split(sub_score, ':')[0] as subject,split(sub_score, ':')[1] as score
from (select student_id,concat_ws(',', concat('语文:', yuwen), concat('数学:', shuxue), concat('英语:', yingyu)) as sub_scoresfrom t_student_score_02)lateral view explode(split(sub_scores, ',')) t as sub_score

执行结果

+-------------+----------+--------+
| student_id  | subject  | score  |
+-------------+----------+--------+
| 001         | 语文       | 89     |
| 001         | 数学       | 95     |
| 001         | 英语       | 77     |
| 002         | 语文       | 92     |
| 002         | 数学       | 83     |
| 002         | 英语       | 97     |
| 003         | 语文       | 81     |
| 003         | 数学       | 94     |
| 003         | 英语       | 88     |
+-------------+----------+--------+

四、数据准备

--建表语句
CREATE TABLE IF NOT EXISTS t_student_score_02
(student_id string, -- 学生idyuwen      bigint,--语文成绩shuxue     bigint, --数学成绩yingyu     bigint  --英语成绩
)COMMENT '学生成绩表';
--数据插入语句
insert into t_student_score_02
select student_id,sum(case when subject = '语文' then score end) as yuwen,sum(case when subject = '数学' then score end) as shuxue,sum(case when subject = '英语' then score end) as yingyu
from t_student_score
group by student_id

相关推荐

  1. 行转列-collect_list,collect_set进行简单行转列
  2. 行转列-使用transform进行有序行转列
  3. 行转列-使用transform进行有序行转列-多列一一对应
  4. 行转列-多行转多列(竖表转横表)
  5. 列转行-多列转多行(横表变竖表)
  6. 列转行-lateral view explode列转行
  7. 列转行-explode_outer和lateral view outer
  8. 列转行-posexplode多列对应转行
  9. 列转行-lateral view outer posexplode及posexplode_outer多列对应转行
关键字:列转行-多列转多行(横表变竖表)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: