简述Hive的开窗函数有哪些 ?

参考回答

Hive中的开窗函数(Window Functions)是一类用于对查询结果集中的数据进行窗口级别的计算的函数,主要用于分析任务,如排名、聚合等。常见的开窗函数包括:

  1. ROW_NUMBER()
    • 用于为每一行数据分配一个唯一的行号,按指定的窗口进行排序。
  2. RANK()
    • 为每一行数据分配一个排名,排名相同的行会得到相同的排名,但排名之间会跳跃。例如,如果有两个相同排名的行,它们的下一个排名会跳过一个数。
  3. DENSE_RANK()
    • RANK()类似,但排名不会跳跃。当有两个相同排名的行时,下一个排名会紧跟着。
  4. NTILE(n)
    • 将数据分为n个桶,返回每一行所在桶的编号。
  5. LEAD()
    • 返回当前行之后n行的数据,通常用于分析当前数据和后续数据之间的关系。
  6. LAG()
    • 返回当前行之前n行的数据,通常用于分析当前数据和前序数据之间的关系。
  7. FIRST_VALUE()
    • 返回窗口中的第一行数据的值。
  8. LAST_VALUE()
    • 返回窗口中的最后一行数据的值。
  9. NTH_VALUE()
    • 返回窗口中第n行的值。

详细讲解与拓展

  1. ROW_NUMBER()
    • ROW_NUMBER()是为查询结果集中的每一行分配一个唯一的数字编号。在ORDER BY排序的基础上,每一行都会有一个唯一的行号。这在需要按某种规则排序并进行分组时非常有用。
    • 例如,假设你想根据订单金额给每一笔订单分配一个行号,可以使用ROW_NUMBER()来实现。
    • 示例:
      SELECT order_id, order_amount,
          ROW_NUMBER() OVER (ORDER BY order_amount DESC) AS rank
      FROM orders;
      
  2. RANK()
    • RANK()为查询结果中的每一行分配排名,排名相同的行会得到相同的排名,但会跳过下一个排名。例如,如果两行并列排名第一,接下来的排名是3,而不是2。
    • 示例:
      SELECT order_id, order_amount,
          RANK() OVER (ORDER BY order_amount DESC) AS rank
      FROM orders;
      

      如果有两笔订单金额相同且最大,它们都会被排名为1,接下来的订单会被排名为3。

  3. DENSE_RANK()
    • DENSE_RANK()RANK()类似,但它不会跳跃排名。即使两行的排名相同,后续的行也会紧接着进行排名。
    • 示例:
      SELECT order_id, order_amount,
          DENSE_RANK() OVER (ORDER BY order_amount DESC) AS rank
      FROM orders;
      

      对于相同金额的订单,它们会被排名为1,2,而不是跳到3。

  4. NTILE(n)
    • NTILE(n)函数将结果集分为n个桶,并返回每一行数据所属的桶编号。例如,如果将数据分成4个桶,每一行会返回一个从1到4的桶编号。
    • 示例:
      SELECT order_id, order_amount,
          NTILE(4) OVER (ORDER BY order_amount DESC) AS bucket
      FROM orders;
      

      这会将订单按金额降序排序,并将它们分为4个桶。

  5. LEAD()
    • LEAD()函数用于获取当前行之后的某一行的值。比如,获取当前订单的下一笔订单的金额。
    • 示例:
      SELECT order_id, order_amount,
          LEAD(order_amount, 1) OVER (ORDER BY order_id) AS next_order_amount
      FROM orders;
      

      该查询会返回每个订单金额以及下一笔订单的金额。

  6. LAG()
    • LAG()函数与LEAD()相反,用于获取当前行之前的某一行的值。通常用于比较当前行和前一行的数据。
    • 示例:
      SELECT order_id, order_amount,
          LAG(order_amount, 1) OVER (ORDER BY order_id) AS prev_order_amount
      FROM orders;
      

      该查询会返回每个订单金额以及上一笔订单的金额。

  7. FIRST_VALUE()
    • FIRST_VALUE()返回窗口中第一行的值,通常用于获取一个窗口中最早的一行数据。
    • 示例:
      SELECT order_id, order_amount,
          FIRST_VALUE(order_amount) OVER (PARTITION BY customer_id ORDER BY order_date) AS first_order_amount
      FROM orders;
      

      该查询会返回每个顾客的第一笔订单金额。

  8. LAST_VALUE()
    • LAST_VALUE()返回窗口中最后一行的值。可以与RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING结合使用来确保得到窗口的最后一行。
    • 示例:
      SELECT order_id, order_amount,
          LAST_VALUE(order_amount) OVER (PARTITION BY customer_id ORDER BY order_date
                                         ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_order_amount
      FROM orders;
      

      该查询返回每个顾客的最后一笔订单金额。

  9. NTH_VALUE()
    • NTH_VALUE()返回窗口中的第n行的值。n可以是任意数字,允许访问窗口中的特定行。
    • 示例:
      SELECT order_id, order_amount,
          NTH_VALUE(order_amount, 3) OVER (PARTITION BY customer_id ORDER BY order_date) AS third_order_amount
      FROM orders;
      

      该查询返回每个顾客的第三笔订单金额。

总结

Hive的开窗函数提供了对数据进行窗口级别计算的强大功能。常见的函数包括ROW_NUMBER()RANK()DENSE_RANK()NTILE()LEAD()LAG()FIRST_VALUE()LAST_VALUE()NTH_VALUE(),它们可用于处理排名、分桶、前后行数据比较等任务。通过合理使用开窗函数,可以简化复杂的查询逻辑并优化性能。

发表评论

后才能评论