如何计算小于 Hive 表中特定行的行数?
Posted
技术标签:
【中文标题】如何计算小于 Hive 表中特定行的行数?【英文标题】:How to count the rows which is lesser than a particular row in a Hive table? 【发布时间】:2016-10-02 19:50:06 【问题描述】:考虑 Hive 中的下表
+------+------+
| id | res |
+------+------+
| 1 | 55 |
| 2 | 10 |
| 3 | 89 |
| 4 | 100 |
| 5 | 80 |
| 6 | 55 |
| 7 | 70 |
| 8 | 35 |
| 9 | 46 |
| 10 | 51 |
+------+------+
现在我必须计算小于特定行中 res 值的行数。
对于上表,输出应该是
+------+------+
| id |count |
+------+------+
| 1 | 4 |
| 2 | 0 |
| 3 | 8 |
| 4 | 9 |
| 5 | 7 |
| 6 | 4 |
| 7 | 6 |
| 8 | 1 |
| 9 | 2 |
| 10 | 3 |
+------+------+
【问题讨论】:
【参考方案1】:您可以尝试RANK OVER
功能。
Hiveql 示例
select
id,
res,
rank() over (ORDER BY res) as rank
from
my_table
order by
res
阅读更多 here 和 here。
【讨论】:
???您的查询返回:(2,10,1) (8,35,2) (9,46,3) (10,51,4) (1,55,5) (6,55,5) (7,70,7) (5,80,8) (3,89,9) ( 4,100,10)
,这不是想要的结果。你运行你的查询了吗?如果我对这个主题感兴趣,请告诉我。
@ozw1z5rd 我能看到的唯一区别是起始索引。 Rank
正在返回从 1 开始的索引。其余一切都相同。
完美!我错过了,它可以在没有叉积的情况下工作。【参考方案2】:
瞧'
+-----+------+
| id | _c1 |
+-----+------+
| 1 | 4 |
| 2 | 0 |
| 3 | 8 |
| 4 | 9 |
| 5 | 7 |
| 6 | 4 |
| 7 | 6 |
| 8 | 1 |
| 9 | 2 |
| 10 | 3 |
+-----+------+
这很容易而且很疯狂,因为这个查询会产生叉积。当然,对于每一行,您必须找到所有值较小的行,看起来像叉积的东西是隐含的。
SELECT id, SUM(IF ( c.res1 > c.res2, 1 , 0 ))
FROM (
SELECT id, a.res AS res1, b.res AS res2
FROM test_4 AS a
INNER JOIN (
SELECT res
FROM test_4
) b
) c
GROUP BY id;
【讨论】:
【参考方案3】:您可以执行以下操作,但请记住从排名结果中删除 1,因为我们不检查
select
id,
res,
rank() over (ORDER BY res) -1 as rank
FROM point
ORDER BY id
或者很长的路:
由于 Hive 不支持 CTE(它基于 SQL-92 标准),我们将不得不使用子查询来代替。
假设:我将同时包含 ID 和 RES 的表称为 POINT。
Select id, sum(comparison) as count
From (
Select
a.id,
a.res as res1,
b.res as res2,
Case when a.res > b.res then 1
Else 0
End as comparison
FROM point a
CROSS JOIN point b
) c
GROUP BY id
请测试并告诉我。
【讨论】:
【参考方案4】:排名可能是要走的路,但这里有一个有趣的选择:
SELECT mt.id AS id
, mt.res AS res
, COUNT(1) OVER (PARTITION BY NULL ORDER BY mt.res ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - 1 AS cnt
FROM my_table mt
【讨论】:
以上是关于如何计算小于 Hive 表中特定行的行数?的主要内容,如果未能解决你的问题,请参考以下文章