HIVESQL中row_number使用

来源:互联网 发布:java socket 发送 编辑:程序博客网 时间:2024/06/08 01:33
row_number()在hive中是一个函数,必须带一个或者多个列参数,如row_number(col1, ....),它的作用是按指定的列进行分组生成行序列,在row_number(a,b) 时,若两条记录的a,b列相同,则行序列+1,否则重新计数。
因为hive是基于mapreaduce的,必须保证row_number执行是在reduce中,并且row_number中使用的列中,列值相同的记录要再同一个reduce中,否则row_number的行为是无意义的。 
实例:
目前有一个表app_product_da,需要求出user_log_acct,item_sku_id维度下最近生成的一条数据。
实现如下:

方式一:

select  t2.user_log_acct,t2.item_sku_id,t2.timefrom (select *  from (select * from app.app_product_da where dt = 'yesterday') t1 distribute by item_sku_id sort by user_log_acct,item_sku_id,time desc) t2where row_number(t2.user_log_acct, t2.item_sku_id) = 1;
方式二:

--由于item_sku_id数据量比较大,distribute by item_sku_id 生成的reduce数量比较多,性能比较低;可以修改如下,100可以根据不同情况来调:select  t2.user_log_acct,t2.item_sku_id,t2.timefrom (select *  from (select * from app.app_product_da where dt = 'yesterday') t1 distribute by pmod(item_sku_id, 100) sort by user_log_acct,item_sku_id,time desc) t2where row_number(t2.user_log_acct, t2.item_sku_id) = 1;
方式三:
--由于有可能有些hive版本不知道上面两种直接where后面row_number(t2.user_log_acct, t2.item_sku_id) = 1select  t3.user_log_acct,t3.item_sku_id,t3.timefrom(select   t2.user_log_acct ,t2.item_sku_id ,t2.time ,row_number(t2.user_log_acct, t2.item_sku_id) r_num from  (select *   from  (select * from app.app_product_da where dt = 'yesterday') t1  distribute by pmod(item_sku_id, 100)  sort by user_log_acct,item_sku_id,time desc ) t2) t3 where t3.r_num = 1;
注意点:
1.使用子查询保证row_number在reduce端执行。
2.使用distribute by item_sku_id sort by user_log_acct,item_sku_id,time desc来保证item_sku_id相同的记录被分配到相同的reduce中。 

1 0
原创粉丝点击