Hive row_number() 中的自定义排序,按窗口函数排序

Posted

技术标签:

【中文标题】Hive row_number() 中的自定义排序,按窗口函数排序【英文标题】:Customised ordering in Hive's row_number() over partition by order by window function 【发布时间】:2020-06-02 16:46:07 【问题描述】:

我有一个带有标识符列id 的表和另一个带有字符串值column_b 的列,我想在column_b 上进行客户订购。假设column_b 由值A、B、C、D 组成。

row_number() over() 在 Hive 中可以使用的语法是:

SELECT id, column_b, row_number() over(partition by id order by column_b) as row_id
FROM   some_table

example 的示例请参见此处

但是,我想在column_b 上进行自定义排序,而不是按字母排序。上面的语法会产生类似:

相反,我想使用A, C, D, B 的顺序明确地按 column_b 排序,即:

我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

使用 case 语句明确指定顺序。您可以在order by 中使用其他标量函数:

SELECT id, column_b, 
       row_number() over(partition by id order by case column_b
                                                       when 'A' then '1'
                                                       when 'C' then '2'
                                                       when 'D' then '3'
                                                       when 'B' then '4'
                                                       --add more cases
                                                       --for example other values sort
                                                       --in natural order  
                                                       else column_b 
                                                       --or use constant
                                                       --to make sure 
                                                       --everything else is greater than 4 
                                                       --like this  else concat('5',column_b)
                                                  end 
                         ) as row_id
  FROM some_table

您也可以在子查询中计算订单列并在窗口中使用它,它的工作原理是一样的:

SELECT id, column_b, 
       row_number() over(partition by id order by orderby) as row_id
  FROM (select t.*, 
               case column_b
                    when 'A' then '1'
                    when 'C' then '2'
                    when 'D' then '3'
                    when 'B' then '4'  
                    else concat('5',column_b) 
               end orderby
           from some_table t
        ) s

【讨论】:

完美运行,我更喜欢第一个版本,因为我认为它更容易阅读。【参考方案2】:

请使用下面的简单查询,

select id, column_b,row_id from
(select id, column_b,row_id from table order by mod(row_id,2) != 0
union all
select id, column_b,row_id from table order by mod(row_id,2) = 0) qry;

【讨论】:

以上是关于Hive row_number() 中的自定义排序,按窗口函数排序的主要内容,如果未能解决你的问题,请参考以下文章

Spark SQL自定义函数

Hive之row_number() over分组排序

Hive实现自增列的两种方法

[HIVE] rank() dense_rank() row_number()的学习

HIVE分组排序问题

hive row_number等窗口分析函数