在hive中经常需要使用到排序,hive中的排序函数有多种,可在相关文档中查阅具体的使用方法,在项目中用到了row_number()来做排序。简单的用法在这里就
不做赘述了,项目具体需求如下:
表tbl_custinfo结构如下
create table tbl_custinfo( custno string,--客户号 acctno string,--账号 cardno string,--卡号 recdate string,--卡审核日期 appid string,--卡申请id product string,--卡种 cardtype string --卡申请时卡种 ) partitioned by(pt string) row format delimited fields terminated by ',' stored as rcfile;
现在要求同一个客户下,取卡审核日期小的卡,若卡审核日期相同,取卡申请id小的卡,若卡申请id相同,则取卡种和卡申请时卡种相同的卡。
原始数据:
1002 65898 622589785645238 20161101 V9875624201 106 1027------① 1002 65898 655812318977101 20161101 V9875624201 1027 1027------② 1003 12876 688951011942014 20050521 Z1021540014 301 301-------③
一开始不知道如何实现,按卡审核日期和卡申请id排序好处理,但是要取取卡种和卡申请时卡种相同的卡就不太好处理,原先的想法是这样的:
select * from (select *,row_number() over(distribute by custno sort by recdate asc,appid asc,product=cardtype) as rank from tbl_custinfo where pt='20161015') a where a.rank=1;mapreduce不报错,正常执行,
1002 65898 622589785645238 20161101 V9875624201 106 1027 1------① 1002 65898 655812318977101 20161101 V9875624201 1027 1027 2------② 1003 12876 688951011942014 20050521 Z1021540014 301 301 1------③但是客户号为1002的排序结果不正确,②应该排序为1。在同事的提醒下换了个思路解决:
select * from (select *,row_number() over(distribute by custno sort by recdate asc,appid asc,case when product=cardtype then '1' else '2' end asc) as rank from tbl_custinfo where pt='20161015') a where a.rank=1;
结果显示是正确的。
1002 65898 622589785645238 20161101 V9875624201 1027 1027 1------① 1002 65898 655812318977101 20161101 V9875624201 106 1027 2------② 1003 12876 688951011942014 20050521 Z1021540014 301 301 1------③