🌈严以律己
🌈甜以待你
Tips
先养眼,再看题
❤️
今天还是小姐姐镇楼

这次我们主要讨论的
行专列,列转行
照旧,刷题复习知识点


Question
step 0
请将原始数据转换下格式
原始数据
| username | subject | score |
| 张三 | 语文 | 80 |
| 张三 | 数学 | 90 |
| 张三 | 英语 | 70 |
| 张三 | 生物 | 85 |
| 李四 | 语文 | 80 |
| 李四 | 数学 | 92 |
| 李四 | 英语 | 76 |
| 李四 | 生物 | 88 |
| 码农 | 语文 | 60 |
| 码农 | 数学 | 82 |
| 码农 | 英语 | 96 |
| 码农 | 生物 | 78 |
期望数据
| username | 数学 | 语文 | 英语 | 生物 |
| 张三 | 90 | 80 | 70 | 85 |
| 李四 | 92 | 80 | 76 | 88 |
| 码农 | 82 | 60 | 96 | 78 |


Answer
step 1
首先由题可知,这个需求是将属于列转行的题
因此我们首先要想到的列转行的关键字
case when then else end
首先我们还是从一个小demo开始讲起
在我们的工作中。
比如要存储用户性别信息
一般使用0或1来进行存储
这时候我们就需要对数字转换为汉字
select if(sex=1,'男','女') as a from table_a;

可是如果中间出现了性别不详,那么if方法将会比较尴尬,这时候就衍生出case when ,来同时处理一个字段多个值。
select
case
when sex = '0' then '女'
when sex = '1' then '男'
else '不详'
end;
当我们理解上面的小demo后,就再来看题
-- 列转行-- 这里的max是为了将无数据的值设为0,避免出现nullSELECT username ,MAX(CASE subject WHEN '数学' THEN score ELSE 0 END ) 数学,MAX(CASE subject WHEN '语文' THEN score ELSE 0 END ) 语文,MAX(CASE subject WHEN '英语' THEN score ELSE 0 END ) 英语,MAX(CASE subject WHEN '生物' THEN score ELSE 0 END ) 生物FROM stu_scoreGROUP BY username;


扩展
step 2
当我们掌握列转行后,我们可以再扩展行转列
union all
原始数据和期望数据就是从上面的数据,来反过来去求
union和union all的区别?
首先都是将两个结果集合并为一个,
但union会将数据去重,union all则不去重。
select username, '数学' subject , math as score from test.stu_score2UNION ALLselect username, '语文' subject, chinese as score from test.stu_score2UNION ALLselect username, '英语' subject, english as score from test.stu_score2UNION ALLselect username, '生物' subject, biological as score from test.stu_score2order by username,subject;


扩展
step 3
同样是行转列,我们有时候可能需要需要
单列转多行:concat_ws
多行转单列:lateral view explode
这次讲的方法,主要适用于hive中
首先单列转多行:concat_ws
原始数据
| user_id | order_id |
| 1 | 100 |
| 1 | 101 |
| 1 | 102 |
| 2 | 100 |
| 2 | 101 |
| 3 | 100 |
期望数据
| user_id | order_value |
| 1 | 100,101,102 |
| 2 | 100,101 |
| 3 | 100 |

期望数据可以看出,
我们需要根据id进行分组,并用逗号进行区分
selectuser_id,concat_ws(',',collect_list(order_id)) as order_valuefrom col_liegroup by user_id;


然后是多行转单列:lateral view explode
原始数据和期望数据如上,来反过来去求
期望数据可以看出,
我们需要按照order_value进行切割成单元素
selectuser_id,order_value,order_idfrom lie_collateral view explode(split(order_value,',')) num as order_id


以上就是针对行专列,列转行的讲解和案例
如果有需要,大家可以在评论区留言呀
如果我会的话会进行讲解,不会的话就装作看不见,哈哈哈



郭大熊的公众号
个人博客 : www.guodaxiong.com
如果不曾见过阳光,我本可以忍受黑暗
Hi GuoDaXiong
我是狗子
祝你幸福







