“
”
01
—
需求描述
已知学生成绩表如下,分别有三个科目英语、数学、历史,现按照如下规则对表进行转换。保持英语、数学、历史顺序不变。

02
—
数据准备
with base as (select 'tom' as name, 80 as english, 90 as math, 100 as historyunion allselect 'jery' as name, 30 as english, 60 as math, 70 as history)
03
—
数据分析
3.1 lateral view explode(array()) 方法
with base as (select 'tom' as name, 80 as english, 90 as math, 100 as historyunion allselect 'jery' as name, 30 as english, 60 as math, 70 as history)select name, subject, case when subject='english' then englishwhen subject='math' then mathwhen subject='history' then historyend as scorefrom (select name, english, math, historyfrom base) t lateral view explode(array('english', 'math', 'history')) tmp as subject
3.2 使用stack()方法

从上面的 该函数的使用来看,stack()函数本质就是一个行转列函数,该函数也可以与lateral view 连用。下面我们就用该函数来实现。
方法1:lateral view stack()
with base as (select 'tom' as name, 80 as english, 90 as math, 100 as historyunion allselect 'jery' as name, 30 as english, 60 as math, 70 as history)selectname,subject,scorefrom baselateral view stack(3, 'english',english, 'math',math,'history',history) tmp as subject,score
方法2:直接使用stack()函数
with base as (select 'tom' as name, 80 as english, 90 as math, 100 as historyunion allselect 'jery' as name, 30 as english, 60 as math, 70 as history)select stack(3,name, 'english', english,name, 'math', math,name, 'history', history) as (name, subject, score)from base;

with base as (select 'tom' as name, 80 as english, 90 as math, 100 as historyunion allselect 'jery' as name, 30 as english, 60 as math, 70 as history)select name,subject,scorefrom (select name, array(struct('history', history), struct('math', math), struct('history', history)) as scoresfrom base) tlateral view inline(scores) tmp as subject, score

04
—
小结
本文通过具体的案例来分析hivesql中具体行转列的技巧和方法,文中具体给出了三种方法,分别利用explode()函数、stack()函数以及inline()函数来完成,解决了传统union all进行行转列代码片段重复的问题,实现方式上较为优雅。

SQL进阶技巧:如何计算先进先出库龄问题?
SQL进阶技巧:如何计算重叠区间合并问题?
数仓建模:DWS层该如何建设?如何设计通用数据模型?
文章转载自会飞的一十六,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




