窗口函数:实现sql查询结果列转行

0 前言

       我们在写Sql语句的时候没经常会遇到将查询结果列转行,例如做vintage报表的时候,SqlServer中有了PIVOT/UNPIVOT函数可以快速实现行转列和列转行的操作,然而hive中没有,大多数人都是通过写一系列的case when函数来实现,个人觉得使用case when这种方法虽然很好,但是很繁琐,这里抛砖引玉一下,通过使用窗口函数来实现列转换操作。

1 需求描述

废话不说,直接上表,说明咱们需要处理的问题:

                                                       表   1
月份 期数 金额
2019/01 1 1000000
2019/01 2 1100000
2019/01 3 1200000
2019/02 1 1400000
2019/02 2 1000000
2019/02 3 1500000

                                     

                                                      表   2
月份 期数1_金额 期数2_金额 期数3_金额
2019/01 1000000 1100000 1200000
2019/02 1400000 1000000 1500000

        我们需要将表1格式的数据转换成表2格式的数据,就是我们将要解决的列转行问题,大多数人使用case when 实现,这里我们使用窗口函数中的lead()函数实现,lead(column,n)获取当前数据行按照某种排序规则的下n行数据的某个字段。

2 操作实现  

2.1 插入数据

假定你已经建好了表test_table,包含date、term、jine这3个字段,插入数据:

insert into test_table values('2019/01', '1','1000000');
insert into test_table values('2019/01', '2','1100000');
insert into test_table values('2019/01', '3','1200000');
insert into test_table values('2019/02', '1','1400000');
insert into test_table values('2019/02', '2','1000000');
insert into test_table values('2019/02', '3','1500000');

2.2 列转行实现

select date, term1_jine, term2_jine, term3_jine
from 
(select date, jine term1_jine,
    lead(jine,1) over(partition by date order by term) term2_jine,
    lead(jine,2) over(partition by date order by term) term3_jine,
    row_number() over(partition by date order by term) row_num
    from test_table) a
where row_num = 1

或者
select date, jine term1_jine,
    lead(jine,1) over(partition by date order by term) term2_jine,
    lead(jine,2) over(partition by date order by term) term3_jine,
    row_number() over(partition by date order by term) row_num
    from test_table
having row_num = 1

  (需要说明一下,有些数据库环境不支持这样写哦)

       这样你就可以得到表2格式的数据啦。顺便说一下,在你做vintage报表的时候,也可以使用这样的方法实现你的需求哦。

3 总结

       说一点点废话哈,经常使用sql的童鞋,建议把窗口函数学一下,可以实现很多复杂的任务,有时间的话,我会继续写一下日常使用窗口函数解决复杂的问题的。

窗口函数:实现sql查询结果列转行_第1张图片

你可能感兴趣的:(sql,hive,窗口函数)