Hive 中的窗口函数
Windowing function in Hive
我正在探索 Hive 中的窗口函数,我能够理解所有 UDF 的功能。虽然,我无法理解我们与其他功能一起使用的分区依据和排序依据。以下是与我计划构建的查询非常相似的结构。
SELECT a, RANK() OVER(partition by b order by c) as d from xyz;
只是想了解这两个关键字所涉及的后台进程。
感谢帮助:)
RANK()
分析函数为数据集中每个分区中的每一行分配一个等级。
PARTITION BY
子句确定如何分配行(如果是 hive,则在 reducer 之间)。
ORDER BY
确定行在分区中的排序方式。
第一阶段按分配,数据集中的所有行都分配到分区中。在 map-reduce 中,每个映射器根据 partition by
对行进行分组,并为每个分区生成文件。 Mapper 根据 order by
.
对分区部分进行初始排序
第二阶段,所有行在每个分区内排序。
在 map-reduce 中,每个 reducer 获取 mappers 生成的分区文件(部分分区),并根据 order by
对整个分区中的行(部分结果排序)进行排序。
第三,等级函数为分区中的每一行分配等级。正在为每个分区初始化 Rank 函数。
对于分区排名中的第一行,从 1 开始。对于每个下一行 Rank=previous row rank+1
。具有相同值的行(按顺序指定)给出相同的排名,如果两行共享相同的排名,则下一行排名不连续。
不同的分区可以在不同的减速器上并行处理。可以在同一个减速器上处理小分区。 Rank 函数在越过分区边界时重新初始化,并从每个分区的 rank=1 开始。
示例(行已在分区内分区和排序):
SELECT a, RANK() OVER(partition by b order by c) as d from xyz;
a, b, c, d(rank)
----------------
1 1 1 1 --starts with 1
2 1 1 1 --the same c value, the same rank=1
3 1 2 3 --rank 2 is skipped because second row shares the same rank as first
4 2 3 1 --New partition starts with 1
5 2 4 2
6 2 5 3
如果需要连续排名,使用dense_rank
函数。 dense_rank
将为上述数据集中的第三行生成 rank=2。
row_number
函数将为分区中从1开始的每一行分配一个位置编号。具有相同值的行将获得不同的连续编号。
SELECT a, ROW_NUMBER() OVER(partition by b order by c) as d from xyz;
a, b, c, d(row_number)
----------------
1 1 1 1 --starts with 1
2 1 1 2 --the same c value, row number=2
3 1 2 3 --row position=3
4 2 3 1 --New partition starts with 1
5 2 4 2
6 2 5 3
重要说明: 对于具有相同值的行 row_number
或其他此类分析函数可能具有不确定的行为并产生与 运行 不同的数字运行。上述数据集中的第一行可能接收到数字 2,第二行可能接收到数字 1,反之亦然,因为它们的顺序不确定,除非您将更多列 a 添加到 order by
子句。在这种情况下,所有行将始终具有与 运行 运行 相同的 row_number,它们的顺序值不同。
我正在探索 Hive 中的窗口函数,我能够理解所有 UDF 的功能。虽然,我无法理解我们与其他功能一起使用的分区依据和排序依据。以下是与我计划构建的查询非常相似的结构。
SELECT a, RANK() OVER(partition by b order by c) as d from xyz;
只是想了解这两个关键字所涉及的后台进程。
感谢帮助:)
RANK()
分析函数为数据集中每个分区中的每一行分配一个等级。
PARTITION BY
子句确定如何分配行(如果是 hive,则在 reducer 之间)。
ORDER BY
确定行在分区中的排序方式。
第一阶段按分配,数据集中的所有行都分配到分区中。在 map-reduce 中,每个映射器根据 partition by
对行进行分组,并为每个分区生成文件。 Mapper 根据 order by
.
第二阶段,所有行在每个分区内排序。
在 map-reduce 中,每个 reducer 获取 mappers 生成的分区文件(部分分区),并根据 order by
对整个分区中的行(部分结果排序)进行排序。
第三,等级函数为分区中的每一行分配等级。正在为每个分区初始化 Rank 函数。
对于分区排名中的第一行,从 1 开始。对于每个下一行 Rank=previous row rank+1
。具有相同值的行(按顺序指定)给出相同的排名,如果两行共享相同的排名,则下一行排名不连续。
不同的分区可以在不同的减速器上并行处理。可以在同一个减速器上处理小分区。 Rank 函数在越过分区边界时重新初始化,并从每个分区的 rank=1 开始。
示例(行已在分区内分区和排序):
SELECT a, RANK() OVER(partition by b order by c) as d from xyz;
a, b, c, d(rank)
----------------
1 1 1 1 --starts with 1
2 1 1 1 --the same c value, the same rank=1
3 1 2 3 --rank 2 is skipped because second row shares the same rank as first
4 2 3 1 --New partition starts with 1
5 2 4 2
6 2 5 3
如果需要连续排名,使用dense_rank
函数。 dense_rank
将为上述数据集中的第三行生成 rank=2。
row_number
函数将为分区中从1开始的每一行分配一个位置编号。具有相同值的行将获得不同的连续编号。
SELECT a, ROW_NUMBER() OVER(partition by b order by c) as d from xyz;
a, b, c, d(row_number)
----------------
1 1 1 1 --starts with 1
2 1 1 2 --the same c value, row number=2
3 1 2 3 --row position=3
4 2 3 1 --New partition starts with 1
5 2 4 2
6 2 5 3
重要说明: 对于具有相同值的行 row_number
或其他此类分析函数可能具有不确定的行为并产生与 运行 不同的数字运行。上述数据集中的第一行可能接收到数字 2,第二行可能接收到数字 1,反之亦然,因为它们的顺序不确定,除非您将更多列 a 添加到 order by
子句。在这种情况下,所有行将始终具有与 运行 运行 相同的 row_number,它们的顺序值不同。