【发布时间】:2025-12-12 04:10:01
【问题描述】:
如何在 Hive SQL 中重写下面的查询 我已经在 Oracle SQL 中尝试了以下内容,它可以工作,但需要在 Hive QL 中编写相同的代码
select * from sales order by unit_price fetch with ties
【问题讨论】:
标签: sql oracle hive hiveql ranking-functions
如何在 Hive SQL 中重写下面的查询 我已经在 Oracle SQL 中尝试了以下内容,它可以工作,但需要在 Hive QL 中编写相同的代码
select * from sales order by unit_price fetch with ties
【问题讨论】:
标签: sql oracle hive hiveql ranking-functions
Oracle 的 ORDER BY .. FETCH NEXT N ROWS WITH TIRES 用于将返回的 top N(使用 ORDER BY)行数限制为 NEXT(FIRST)指定的数量。而使用轮胎意味着如果某些行具有相同的值顺序,除了指定的行数之外,它们也将被返回。
Hive 没有 FETCH 功能。有LIMIT,不支持WITH TIRES。
您可以使用分析的 dense_rank() 函数加上 WHERE 过滤器来实现类似的功能。例如,我们需要获取 5 个最低价格的销售,如果有相同价格的销售,也返回它们。 dense_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
【讨论】:
dense_rank() 不像 with ties 那样做。
用窗口函数来复制这是相当棘手的。 fetch with ties 返回到第 nth 行,然后返回具有相同值的所有行。所以,一种方法是:
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 个1s。 dense_rank() 和 rank() 将返回所有行。
【讨论】: