问题描述
如何在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个1
。 dense_rank()
和rank()
将返回所有行。