MYSQL之窗口函数

本文介绍了MySQL8.0引入的窗口函数,包括如何使用PARTITIONBY和ORDERBY进行数据分组和排序,以及聚合函数、排名函数和行间比较函数LEAD(),LAG(),FIRST_VALUE(),LAST_VALUE()的应用实例。这些功能扩展了SQL查询在数据分析中的能力,支持更精确的业务决策制定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.窗口函数

        MySQL 8.0 引入了窗口函数(也称为分析函数),这是一项对 MySQL 功能的重大扩展,提供了在 SQL 查询中进行更复杂的统计和数据分析功能。窗口函数允许用户对一组行(称为窗口)执行计算,这些行与查询结果中的当前行有某种关系,而不用对整个查询结果集分组或排序。使用窗口函数可以执行各种操作,如求和、计数、平均值计算,以及在数据集内进行行之间的比较等。窗口函数的基本语法:

                 <窗口函数> OVER ( [PARTITION BY <列名>] [ORDER BY <排序规则>] )

  • PARTITION BY:这部分用于将数据分为特定的分区,窗口函数会在每个分区内独立计算。
  • ORDER BY:用于在每个分区内对数据进行排序,窗口函数的计算可以依赖于这个顺序。
  • 窗口帧:是指在 ORDER BY 中定义的当前行的上下文窗口。窗口帧可以通过 ROWSRANGE 关键字进一步定义。

2.聚合窗口函数

       总数 SUM()平均数AVG()最小数MIN()最大数MAX()统计次数COUNT() 等。

sql实例:

SELECT 
  player_name, 
  game_date,
  points,
  AVG(points) OVER (PARTITION BY player_name ORDER BY game_date) AS avg_points
FROM 
  game_stats;

上述查询会为每个玩家计算其每场比赛至今的平均得分。

3.排名窗口函数

        ROW_NUMBER()RANK()DENSE_RANK()NTILE(n) 

sql实例:

SELECT 
  employee_id,
  sale_date,
  amount,
  RANK() OVER (PARTITION BY employee_id ORDER BY amount DESC) AS rank
FROM 
  sales;

上述查询会为每个玩家计算其每场比赛至今的平均得分。其中row_number、rank、dense_rank的区别如下,对于年龄集合{22,23,22},使用它们的排序结果依次为{1,2,3}、{1,1,3}、{1,1,2}。

NTILE(n) 使用与上三者有所区别,实例如下:

SELECT 
  employee_id,
  sale_date,
  amount,
  NTILE(4) OVER (PARTITION BY employee_id ORDER BY amount DESC) AS quartile
FROM 
  sales;

NTILE(n) 函数用于将分区内的行分成指定数量的几乎等大的组,n 是你指定的组的数量。这会将每个员工的销售记录按销售额分成四个组,每个组包含相同数量的行(或尽可能平均)。每个这些函数都在数据分析和报告中非常有用,特别是当你需要按一定方式排序、分组或排名数据时。它们可以帮助你更好地理解数据,做出更有根据的业务决策。

4.分析窗口函数

  LEAD(), LAG(), FIRST_VALUE(), 和 LAST_VALUE() 是一组窗口函数,用于执行基于行与行之间的比较和关系操作。这些函数可以访问由 ORDER BY 在窗口函数中定义的数据行序列中的其他行,而不​​​​​​​需要进行自连接或复杂的子查询。以下是使用示例。

LEAD() 函数用于访问当前行之后的行(即“领先”的行)。它可以查看当前行后的第 N 行的数据。

示例查询: 假设有一个销售数据表 sales,包括日期和销售额:

SELECT 
  sale_date,
  sales_amount,
  LEAD(sales_amount, 1) OVER (ORDER BY sale_date) AS next_day_sales
FROM 
  sales;

这个查询显示每一天的销售额和下一天的销售额。同样的LAG查询显示每一天的销售额和上一天的销售额

FIRST_VALUE(), 和 LAST_VALUE() 使用有所不同

FIRST_VALUE() 函数用于在窗口帧中访问第一行的数据,使用销售数据表 sales 来展示每月的销售变化,以每月第一天的销售额为基准:

SELECT 
  sale_date,
  sales_amount,
  FIRST_VALUE(sales_amount) OVER (PARTITION BY MONTH(sale_date) ORDER BY sale_date) AS first_day_sales_of_month
FROM 
  sales;

这个查询在每个月份中显示每天的销售额与该月第一天的销售额。

LAST_VALUE() 函数用于在窗口帧中访问最后一行的数据。在使用 LAST_VALUE() 时,必须正确设置窗口帧(使用 ROWS BETWEEN),否则可能得到意料之外的结果,因为窗口默认是从当前行到分区结束。

SELECT 
  sale_date,
  sales_amount,
  LAST_VALUE(sales_amount) OVER (PARTITION BY MONTH(sale_date) ORDER BY sale_date ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS last_day_sales_of_month
FROM 
  sales;

这个查询展示了每月中每天的销售额与该月最后一天的销售额相比。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值