Hive SQL排行榜

问题描述

如何在Hive sql中重新编写下面的查询 我已经在Oracle sql中尝试了以下内容,并且可以使用,但需要在Hive QL中编写相同的内容

select * from sales order by unit_price fetch with ties

解决方法

Oracle的ORDER BY ..获取带有轮胎的下N个行用于将返回的前N行(使用ORDER BY)的行数限制为由NEXT(第一)指定的数目。轮胎表示如果某些行的值顺序相同,则除了指定的行数之外,还将返回它们。

配置单元不具有FETCH功能。有LIMIT,它不支持WITH TIRES。

您可以使用Analytics density_rank()函数以及WHERE过滤器来实现类似的功能。例如,我们需要获取最低价格的5个销售,如果有相同价格的销售,也将它们退回。 density_rank将为相同价格的行分配相同的排名。

select * 
from
(
    select s.*,dense_rank() over(order by unit_price) rnk --lowest unit_price first
                                                      --to get highest price,use order by unit_price DESC
     from sales s 
) 
where rnk<=5  --If there are rows with the same rank,they all will be returned
order by rnk
,

要使用窗口函数进行复制非常棘手。 fetch with ties返回第 n 行,然后返回所有具有相同值的行。因此,一种方法是:

select s.*
from sales *
where s.unit_price <= (select s2.unit_price
                       from sales s2
                       order by unit_price 
                       limit 4,1
                      );

这是不正确的,因为如果少于5行,它将不起作用。另一种使用窗口函数的方法使此问题更易于修复:

select s.*
from (select s.*,max(case when seqnum = 5 then unit_price end) over () as unit_price_5
      from (select s.*,row_number() over (order by unit_price) as seqnum
            from s
           ) s
     ) s
where unit_price <= unit_price_5 or
      unit_price_5 is null;

请注意,内置窗口功能均无法处理这种情况。例如,如果价格是:

1
1
1
1
1
1
2

然后row_number()仅返回前5个1dense_rank()rank()将返回所有行。