HiveSQL中row_number使用介绍

版权声明: https://blog.csdn.net/ah_quwei/article/details/81637881

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.time
from 
(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
) t2
where 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.time
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
where row_number(t2.user_log_acct, t2.item_sku_id) = 1
;

方式三:

--由于有可能有些hive版本不知道上面两种直接where后面row_number(t2.user_log_acct, t2.item_sku_id) = 1
select 
 t3.user_log_acct
,t3.item_sku_id
,t3.time
from
(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中。 

猜你喜欢

转载自blog.csdn.net/ah_quwei/article/details/81637881