深入理解MySQL 8的窗口函数及其应用场景

引言:

MySQL 8的引入为数据库查询带来了一项强大的功能:窗口函数(Window Functions)。这些函数扩展了SQL的能力,允许开发者和数据分析师在保持数据行详情的同时执行高级统计和分析操作。

窗口函数概述:

窗口函数是一类特殊的SQL函数,它们在执行聚合计算时不会像GROUP BY子句那样折叠行,而是允许在定义的数据窗口上执行计算。这个"窗口"指的是一组排序后的行集合,通常是基于某些列的值进行分区。窗口函数可以访问窗口中的其他行而不仅仅是当前行,从而实现对数据的复杂分析。

使用示例

MySQL 8 引入了对窗口函数(Window Functions)的支持,这是一种强大的功能,用于执行数据的分区计算,而不需要将数据分组为单独的行。窗口函数可以对数据集的子集(称为窗口)执行聚合操作, 同时保持行的独立性。以下是一些常用的窗口函数及其使用示例:

  1. ROW_NUMBER(): 为每个分区内的行提供一个唯一的序号。

    sql 复制代码
    SELECT 
        name,
        department,
        salary,
        ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS row_num
    FROM employees;

这个查询会为每个部门内的员工根据薪水降序排列提供一个唯一的序号。

  1. RANK(): 在分区内对行进行排名,相同值的行会有相同的排名,排名之间会有间隔。

    sql 复制代码
    SELECT 
        name,
        department,
        salary,
        RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank
    FROM employees;
  2. DENSE_RANK(): 类似于RANK(),但排名之间不会有间隔。

    sql 复制代码
    SELECT 
        name,
        department,
        salary,
        DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dense_rank
    FROM employees;
  3. SUM(): 计算分区内值的总和。

    sql 复制代码
    SELECT 
        name,
        department,
        salary,
        SUM(salary) OVER (PARTITION BY department) AS department_total_salary
    FROM employees;
  4. AVG(): 计算分区内值的平均值。

    sql 复制代码
    SELECT 
        name,
        department,
        salary,
        AVG(salary) OVER (PARTITION BY department) AS department_avg_salary
    FROM employees;
  5. LEAD() 和 LAG(): 获取分区内当前行的下一行或上一行的值。

    sql 复制代码
    SELECT 
        name,
        department,
        salary,
        LEAD(salary) OVER (PARTITION BY department ORDER BY salary) AS next_highest_salary,
        LAG(salary) OVER (PARTITION BY department ORDER BY salary) AS previous_salary
    FROM employees;
  6. FIRST_VALUE() 和 LAST_VALUE(): 获取分区内的第一个值和最后一个值。

    sql 复制代码
    SELECT 
        name,
        department,
        salary,
        FIRST_VALUE(name) OVER (PARTITION BY department ORDER BY salary DESC) AS highest_earner,
        LAST_VALUE(name) OVER (PARTITION BY department ORDER BY salary DESC 
           RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS lowest_earner
    FROM employees;
  7. NTILE(): 将分区内的行分成指定数量的近似相等的排名组。

    sql 复制代码
    SELECT 
        name,
        department,
        salary,
        NTILE(4) OVER (PARTITION BY department ORDER BY salary DESC) AS quartile
    FROM employees;

在使用LAST_VALUE()函数时,通常需要指定窗口的范围,如示例中的RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING,以确保能够获取到整个分区内的最后一个值。

  1. CUME_DIST(): 计算当前行在其分区中的累积分布位置,其值为当前行之前的所有行数加上当前行(包含重复行)除以分区中的总行数。

    sql 复制代码
    SELECT 
        name,
        department,
        salary,
        CUME_DIST() OVER (PARTITION BY department ORDER BY salary DESC) AS cume_dist
    FROM employees;
  2. PERCENT_RANK(): 计算当前行的百分比排名,类似于RANK(),但表示为介于0和1之间的比例。

sql 复制代码
   SELECT 
       name,
       department,
       salary,
       PERCENT_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS percent_rank
   FROM employees;

这些函数可以在各种数据分析任务中非常有用,例如计算累计总和、移动平均值或者进行排名。窗口函数的一个关键特征是它们允许在不改变原始数据集行数的情况下进行聚合计算。

业务场景应用:

窗口函数在多种业务场景中都有实际的应用价值:

  • 业绩评估: 通过RANK()DENSE_RANK(),可以快速识别出业绩最好或最差的员工。

  • 财务分析: SUM()AVG()窗口函数可以用来计算部门的总薪水或平均薪水,而不会丢失个别员工的薪水信息。

  • 数据挖掘: LEAD()LAG()函数可以用来比较序列数据,例如股票价格的前后变化。

  • 报告和分段: NTILE()可以用于分段用户或产品,以便进行更细致的市场分析。

结论:

MySQL 8的窗口函数为数据库查询提供了前所未有的灵活性和强大的分析能力。无论是数据分析师还是开发者,都可以利用这些工具来提升数据处理的效率和深度。掌握窗口函数的使用将是任何希望在数据驱动决策领域取得成功的专业人士的重要技能。

相关推荐
码界筑梦坊3 分钟前
173-基于Flask的微博舆情数据分析系统
后端·python·数据分析·flask·毕业设计
叁沐28 分钟前
MySQL 28 读写分离有哪些坑?
mysql
DarkAthena1 小时前
【GaussDB】使用MySQL客户端连接到GaussDB的M-Compatibility数据库
数据库·mysql·gaussdb
井云AI1 小时前
井云智能体封装小程序:独立部署多开版 | 自定义LOGO/域名,打造专属AI智能体平台
人工智能·后端·小程序·前端框架·coze智能体·智能体网站·智能体小程序
前端小巷子2 小时前
Vue 3 运行机制
前端·vue.js·面试
Warren982 小时前
Spring Boot 拦截器返回中文乱码的解决方案(附全局优化思路)
java·网络·spring boot·redis·后端·junit·lua
练习时长一年2 小时前
SpringMVC相关自动配置
java·spring boot·后端
Victor3562 小时前
Redis(21)Redis的发布/订阅(Pub/Sub)机制是如何实现的?
后端
Victor3562 小时前
Redis(20) Redis的管道(Pipeline)是如何工作的?
后端
一枚小小程序员哈5 小时前
基于asp.net 的在线餐饮订餐系统的设计与实现/基于c#的网上订餐系统/餐厅管理系统
后端·c#·asp.net