SQL面试题练习 —— 有序行转列

1 题目


有学生各学科分数表,记录了学生的各科分数,请按照学生粒度,生成两列数据分别为学科和分数,要求学科内的顺序与分数顺序一致。

样例数据

在这里插入图片描述

期望结果

在这里插入图片描述

2 建表语句


--建表语句
create table if not exists t17_student_score
(
    student string,
    subject string,
    score   bigint
);

--插入数据

insert into t17_student_score(student, subject, score)
values ('张三', '语文', 95),
       ('张三', '数学', 80),
       ('张三', '英语', 82),
       ('李四', '语文', 90),
       ('李四', '数学', 90),
       ('李四', '英语', 93),
       ('王五', '语文', 88),
       ('王五', '数学', 92),
       ('王五', '英语', 88),
       ('赵六', '语文', 77),
       ('赵六', '数学', 84),
       ('赵六', '英语', 68);

3 题解


  1. 拼接学科和成绩

使用struct将学科和成绩转换为结构体,这样绑定了学科和成绩。

select student,
       struct(subject, score) as subject_score
from t17_student_score

执行结果

在这里插入图片描述

  1. 使用collect_list将结构体转换为数组

使用collect_list函数,将数据进行行转列,得到数组。注意:不同学科顺序是不能保证有序的,有序是巧合。

select student,
       collect_list(struct(subject, score)) as subject_score
from t17_student_score
group by student

执行结果

+----------+----------------------------------------------------+
| student  |                   subject_score                    |
+----------+----------------------------------------------------+
| 张三       | [{"subject":"语文","score":95},{"subject":"数学","score":80},{"subject":"英语","score":82}] |
| 李四       | [{"subject":"语文","score":90},{"subject":"数学","score":90},{"subject":"英语","score":93}] |
| 王五       | [{"subject":"语文","score":88},{"subject":"数学","score":92},{"subject":"英语","score":88}] |
| 赵六       | [{"subject":"语文","score":77},{"subject":"数学","score":84},{"subject":"英语","score":68}] |
+----------+----------------------------------------------------+
  1. 将结构体数组转换为map
select student,
       map_from_entries(collect_list(struct(subject, score)))  as subject_score
from t17_student_score
group by student

执行结果

在这里插入图片描述

  1. 从map中分别取出keys和values作为subjects和scores,得到最终结果。
select student,
       concat_ws(',', map_keys(subject_score))   as subjects,
       concat_ws(',', map_values(subject_score)) as scores
from (select student,
             map_from_entries(collect_list(struct(subject, score))) as subject_score
      from t17_student_score
      group by student) t

执行结果

在这里插入图片描述

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值