Hive中窗口函数的定义分类适用场景示例难点权威详解


文章目录

  • Hive中窗口函数的定义分类适用场景示例难点权威详解
  • 定义
  • 分类和适用场景
  • 为什么使用partition by
  • PARTITION BY和GROUP BY区别
  • 官网示例详解
  • 1. PARTITION BY with one partitioning column, no ORDER BY or window specification
  • 2. PARTITION BY with two partitioning columns, no ORDER BY or window specification
  • 3. PARTITION BY with one partitioning column, one ORDER BY column, and no window specification
  • 4. PARTITION BY with two partitioning columns, two ORDER BY columns, and no window specification
  • 5. PARTITION BY with partitioning, ORDER BY, and window specification
  • 6. Multiple OVER clauses in a single query
  • 7. Aliases with or without the keyword AS
  • 8. WINDOW clause
  • 9. LEAD and LAG functions
  • 10. Distinct counting for each partition
  • 官方链接:


定义

在Hive中,窗口函数(Window Functions)用于对查询结果集中的每一行应用计算,并可以访问和处理其他行的值。窗口函数的定义包括以下几个关键部分:

  1. 窗口函数的语法:
  • 在SELECT语句中使用窗口函数时,通常按照以下语法格式进行定义:
<窗口函数>(<表达式>) OVER (PARTITION BY <分区列> ORDER BY <排序列> [窗口规范])
  1. 窗口函数的名称:
  • 窗口函数可以是聚合函数(如SUM、COUNT、AVG等),也可以是特定的窗口函数(如LEAD、LAG等)。
  • 选择合适的窗口函数根据需要执行相应的计算操作。
  1. 表达式:
  • 表达式是窗口函数所作用的列或表达式,它决定了窗口函数计算的数据来源。
  1. PARTITION BY子句:
  • PARTITION BY子句用于将数据分成逻辑上独立的分区,每个分区都有自己的计算范围。
  • 可以指定一个或多个列作为分区依据,在同一个分区内的行将被视为一个组。
  1. ORDER BY子句:
  • ORDER BY子句用于指定分区内行的排序方式,它决定了窗口函数计算的顺序。
  • 可以指定一个或多个列作为排序依据,在同一个分区内的行将按照指定的排序规则进行排列。
  1. 窗口规范(Window Specification):
  • 窗口规范定义了窗口函数计算的范围和条件。
  • 可以通过使用ROWS BETWEEN子句来指定计算范围,例如当前行和前几行、当前行和后几行等。
  • 窗口规范可以在窗口函数内部直接定义,也可以使用WINDOW子句中命名并在后续的窗口函数中引用。

总结:

  • Hive中窗口函数的定义包括窗口函数的名称、表达式、PARTITION BY子句、ORDER BY子句和窗口规范。
  • PARTITION BY用于分区数据,ORDER BY用于排序,窗口规范用于指定计算范围。
  • 窗口函数的语法格式是 <窗口函数>(<表达式>) OVER (PARTITION BY <分区列> ORDER BY <排序列> [窗口规范])

理解Hive中窗口函数的定义非常重要,因为它们提供了处理复杂分析任务的强大工具,并能够实现对查询结果集的灵活操作。

分类和适用场景

在Hive中,窗口函数可以分为以下几类:

1.排名函数(Ranking Functions):包括RANK、DENSE_RANK、ROW_NUMBER等,用于计算结果集中每一行的排名或编号。

适用场景:

  • 需要对结果集进行排名或编号
  • 根据某个列的值对结果集进行排序并生成排名。

示例:

SELECT RANK() OVER (ORDER BY score DESC) AS rank, name FROM table;

2.聚合函数(Aggregate Functions):包括SUM、COUNT、AVG、MIN、MAX等,在窗口内计算某个列的聚合值。

适用场景:

  • 需要在窗口内进行聚合计算。
  • 例如计算每个分区内的总和、平均值等。

示例:

SELECT SUM(sales) OVER (PARTITION BY category) AS total_sales FROM table;

3.偏移函数(Offset Functions):包括LEAD、LAG等,用于获取当前行前后指定偏移量的行的值。

适用场景:

  • 需要获取当前行前后的特定行的值。
  • 例如查找前几行后几行的数据。

示例:

SELECT name, LEAD(score, 1) OVER (ORDER BY date ASC) AS next_score FROM table;

4.窗口聚合函数(Window Aggregate Functions):包括FIRST_VALUE、LAST_VALUE等,用于获取结果集中每个分区的第一个值或最后一个值。

适用场景:

  • 需要获取每个分区的第一个值或最后一个值。
  • 例如查找每个分区的首尾记录

示例:

SELECT FIRST_VALUE(name) OVER (PARTITION BY category ORDER BY date ASC) AS first_name FROM table;

为什么使用partition by

在Hive中,窗口函数和聚合函数(如SUM、COUNT、AVG等)是两种不同的操作,它们使用PARTITION BY和GROUP BY来实现不同的功能。

窗口函数(Window Functions):

  • 窗口函数用于对查询结果集中的每一行应用计算,并可以访问和处理其他行的值。
  • PARTITION BY子句在窗口函数中用于将数据划分为逻辑上独立的分区,每个分区都有自己的计算范围
  • 使用PARTITION BY可以对每个分区内的数据进行排名、排序、偏移和聚合等操作。

聚合函数(Aggregate Functions):

  • 聚合函数用于对查询结果集进行分组,并对每个组应用聚合计算。
  • GROUP BY子句在聚合函数中用于将数据按照指定的列值进行分组。
  • 使用GROUP BY可以生成每个组的汇总信息,如总计、平均值等。

为什么窗口函数大量使用PARTITION BY而不是GROUP BY?

  1. 窗口函数的计算是在每一行上进行的,而不是在分组后的结果上。因此,使用PARTITION BY可以更灵活地定义每个分区的计算范围,无需对数据进行重新分组。
  2. PARTITION BY允许对结果集的任意部分进行计算,而不仅限于分组级别。
  3. 使用PARTITION BY可以在计算过程中保留原始的行和值顺序,而GROUP BY会将数据重新分组并可能改变顺序。

总结:

  • 窗口函数使用PARTITION BY子句对每个分区进行计算,提供了更灵活的结果集操作方式。
  • 聚合函数使用GROUP BY子句对结果集进行分组,并在每个组上应用聚合计算。

在实际使用时,根据具体需求选择适当的操作方式:如果需要对整个分组进行聚合操作,则使用GROUP BY;如果需要对每个分区内的行进行计算操作,则使用窗口函数和PARTITION BY。

PARTITION BY和GROUP BY区别

在Hive SQL中,PARTITION BY和GROUP BY是两个不同的关键字,用于不同的目的。下面是它们之间的区别:

  1. PARTITION BY:
  • PARTITION BY是用于对表进行分区(Partition)的关键字。
  • 使用PARTITION BY可以将表的数据划分成更小、更易管理的部分。
  • 分区是根据指定的列值将数据拆分为不同的存储单元,每个分区都有自己的目录和文件。
  • 分区可以提高查询性能,因为只需要扫描和处理特定分区的数据,而不是整个表。
  • 在创建表时,使用PARTITIONED BY子句指定要分区的列,并在加载数据时指定分区值。
  • 示例:创建一个按照日期分区的表,每个日期对应一个分区
  1. GROUP BY:
  • GROUP BY是用于对查询结果进行分组(Group)的关键字。
  • 使用GROUP BY可以将查询结果根据一个或多个列的值进行分组。
  • 分组操作将具有相同值的行放在一起,并将它们视为一个组。
  • 在分组的基础上,可以使用聚合函数(如SUM、COUNT、AVG等)计算每个组的聚合结果。
  • GROUP BY通常与SELECT语句中的聚合函数一起使用,用于生成摘要信息、统计报表以及数据分析等任务。
  • 示例:根据部门对员工表进行分组,并计算每个部门的平均薪水。

总结:

  • PARTITION BY用于对表进行分区,将数据划分为更小、更易管理的部分。
  • GROUP BY用于对查询结果进行分组,并进行聚合计算。

在Hive SQL中,可以同时使用PARTITION BY和GROUP BY来更灵活地组织和查询数据。PARTITION BY用于物理存储和数据访问的优化,而GROUP BY用于逻辑上对数据进行分组和聚合。

官网示例详解

以下是对示例的详细说明:

1. PARTITION BY with one partitioning column, no ORDER BY or window specification

SELECT a, COUNT(b) OVER (PARTITION BY c)
FROM T;
  • 使用一个分区列进行分区,没有ORDER BY或窗口规范。
  • 示例中通过使用PARTITION BY子句将数据按照列c进行分区,并计算每个分区内列b的计数。

2. PARTITION BY with two partitioning columns, no ORDER BY or window specification

SELECT a, COUNT(b) OVER (PARTITION BY c, d)
FROM T;
  • 使用两个分区列进行分区,没有ORDER BY或窗口规范。
  • 示例中通过使用PARTITION BY子句将数据按照列c和d进行分区,并计算每个分区内列b的计数。

3. PARTITION BY with one partitioning column, one ORDER BY column, and no window specification

SELECT a, SUM(b) OVER (PARTITION BY c ORDER BY d)
FROM T;
  • 使用一个分区列和一个排序列进行分区,并且没有窗口规范。
  • 示例中通过使用PARTITION BY子句将数据按照列c进行分区,并按照列d进行排序,在每个分区内计算列b的总和。

4. PARTITION BY with two partitioning columns, two ORDER BY columns, and no window specification

SELECT a, SUM(b) OVER (PARTITION BY c, d ORDER BY e, f)
FROM T;
  • 使用两个分区列和两个排序列进行分区,并且没有窗口规范。
  • 示例中通过使用PARTITION BY子句将数据按照列c和d进行分区,并按照列e和f进行排序,在每个分区内计算列b的总和。

5. PARTITION BY with partitioning, ORDER BY, and window specification

SELECT a, SUM(b) OVER (PARTITION BY c ORDER BY d ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM T;
SELECT a, AVG(b) OVER (PARTITION BY c ORDER BY d ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
FROM T;
SELECT a, AVG(b) OVER (PARTITION BY c ORDER BY d ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING)
FROM T;
SELECT a, AVG(b) OVER (PARTITION BY c ORDER BY d ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
FROM T;
  • 使用分区、排序和窗口规范对数据进行操作。
  • 示例中通过使用PARTITION BY子句将数据按照列c进行分区,并按照列d进行排序。窗口规范指定了计算范围,如从无限制的前导行到当前行。
  • 在每个分区内按照指定的排序规则计算列b的总和或平均值。

6. Multiple OVER clauses in a single query

SELECT 
 a,
 COUNT(b) OVER (PARTITION BY c),
 SUM(b) OVER (PARTITION BY c)
FROM T;
  • 单个查询中可以有多个OVER子句,但每个OVER子句仅适用于紧接在其后的函数调用。
  • 示例中第一个OVER子句应用于COUNT(b),第二个OVER子句应用于SUM(b)。

7. Aliases with or without the keyword AS

SELECT 
 a,
 COUNT(b) OVER (PARTITION BY c) AS b_count,
 SUM(b) OVER (PARTITION BY c) b_sum
FROM T;
  • 可以使用别名,并可选择是否使用AS关键字。
  • 示例中为COUNT(b)和SUM(b)添加了别名。

8. WINDOW clause

SELECT a, SUM(b) OVER w
FROM T
WINDOW w AS (PARTITION BY c ORDER BY d ROWS UNBOUNDED PRECEDING);
  • 使用WINDOW子句定义窗口规范。
  • 示例中使用WINDOW子句将窗口规范命名为w,并在后续的OVER子句中引用该命名。
  • 在每个分区内按照指定的排序规则计算列b的总和。

9. LEAD and LAG functions

SELECT a, LEAD(a) OVER (PARTITION BY b ORDER BY C)
FROM T;
SELECT a, LAG(a, 3, 0) OVER (PARTITION BY b ORDER BY C)
FROM T;
  • 使用LEAD和LAG函数获取前一行或后一行的值。
  • 示例中LEAD函数默认获取1行后面的值,没有指定默认值;LAG函数指定了3行的偏移量,并设置默认值为0。

10. Distinct counting for each partition

SELECT a, COUNT(distinct a) OVER (PARTITION BY b)
FROM T;
  • 对每个分区进行不同值的计数。
  • 示例中使用COUNT(distinct a) OVER (PARTITION BY b)对每个分区内的列a进行计数。

以上示例展示了Hive QL窗口函数和分析函数的不同用法,以及如何根据需要进行分区、排序和计算。这些示例可以帮助你理解如何在Hive中使用窗口函数和分析函数来处理数据。