MySQL窗口函数详解

news2024/11/18 14:56:21

MySQL窗口函数详解

MySQL从8.0版本开始引入了窗口函数,这是一个强大的特性,可以大大简化复杂的数据分析任务。本文将详细介绍MySQL窗口函数的概念、语法和常见用法,并结合实际应用场景进行说明。

什么是窗口函数?

窗口函数是一种能够对结果集中的一组行进行操作的函数。它们类似于聚合函数,但不会将结果集缩减为单个行 - 相反,它们为每一行返回一个结果。

窗口函数的语法

基本语法如下:

function_name() OVER (
    [PARTITION BY column_list]
    [ORDER BY column_list]
    [frame_clause]
)
  • function_name: 窗口函数的名称
  • PARTITION BY: 可选,定义行分组的方式
  • ORDER BY: 可选,定义分区内行的排序方式
  • frame_clause: 可选,定义当前分区内的行子集(窗口帧)

常用的窗口函数及其应用场景

1. ROW_NUMBER()

ROW_NUMBER() 为每一行分配一个唯一的整数。

基本用法
SELECT 
    name,
    score,
    ROW_NUMBER() OVER (ORDER BY score DESC) as rank
FROM students;
实际应用场景:查找每个部门的前N名员工

假设我们要找出每个部门薪资最高的3名员工:

CREATE TABLE employees (
    id INT,
    name VARCHAR(50),
    department VARCHAR(50),
    salary DECIMAL(10, 2)
);

INSERT INTO employees (id, name, department, salary) VALUES
(1, 'Alice', 'Sales', 60000),
(2, 'Bob', 'Sales', 50000),
(3, 'Charlie', 'Sales', 55000),
(4, 'David', 'Marketing', 65000),
(5, 'Eve', 'Marketing', 60000),
(6, 'Frank', 'Marketing', 70000),
(7, 'Grace', 'IT', 80000),
(8, 'Henry', 'IT', 75000),
(9, 'Ivy', 'IT', 78000);

SELECT *
FROM (
    SELECT 
        name,
        department,
        salary,
        ROW_NUMBER() OVER (
            PARTITION BY department
            ORDER BY salary DESC
        ) as salary_rank
    FROM employees
) ranked
WHERE salary_rank <= 3
ORDER BY department, salary_rank;

这个查询首先为每个部门的员工按薪资进行排名,然后筛选出排名前三的员工。
在这里插入图片描述

2. RANK() 和 DENSE_RANK()

RANK() 为每一行分配排名,相同值的行获得相同排名,但会产生间隔。
DENSE_RANK() 类似于RANK(),但不会产生间隔。

基本用法
SELECT 
    name,
    score,
    RANK() OVER (ORDER BY score DESC) as rank,
    DENSE_RANK() OVER (ORDER BY score DESC) as dense_rank
FROM students;
实际应用场景:学生成绩排名

假设我们要为学生的考试成绩进行排名,同时展示 RANK() 和 DENSE_RANK() 的区别:

CREATE TABLE student_scores (
    id INT,
    name VARCHAR(50),
    score INT
);

INSERT INTO student_scores (id, name, score) VALUES
(1, 'Alice', 95),
(2, 'Bob', 95),
(3, 'Charlie', 90),
(4, 'David', 88),
(5, 'Eve', 88),
(6, 'Frank', 85);

SELECT 
    name,
    score,
    RANK() OVER (ORDER BY score DESC) as rank_number,
    DENSE_RANK() OVER (ORDER BY score DESC) as dense_rank_number
FROM student_scores;

这个查询展示了学生成绩的排名,同时显示了 RANK() 和 DENSE_RANK() 的区别。RANK() 会在相同分数后产生间隔,而 DENSE_RANK() 不会。
在这里插入图片描述

3. LAG() 和 LEAD()

LAG() 和 LEAD() 允许我们访问当前行之前或之后的行。

基本用法
SELECT 
    date,
    sales,
    LAG(sales) OVER (ORDER BY date) as previous_day_sales,
    LEAD(sales) OVER (ORDER BY date) as next_day_sales
FROM daily_sales;
实际应用场景:计算同比增长率

假设我们要计算每月销售额的同比增长率:

CREATE TABLE monthly_sales (
    year INT,
    month INT,
    sales DECIMAL(10, 2)
);

INSERT INTO monthly_sales (year, month, sales) VALUES
(2022, 1, 10000), (2022, 2, 12000), (2022, 3, 15000),
(2023, 1, 11000), (2023, 2, 13000), (2023, 3, 16000);

SELECT 
    year,
    month,
    sales,
    LAG(sales) OVER (PARTITION BY month ORDER BY year) as prev_year_sales,
    (sales - LAG(sales) OVER (PARTITION BY month ORDER BY year)) / 
    LAG(sales) OVER (PARTITION BY month ORDER BY year) * 100 as growth_rate
FROM monthly_sales
ORDER BY month, year;

这个查询计算了每个月的销售额相比去年同期的增长率。
在这里插入图片描述

4. 聚合窗口函数 (如 SUM(), AVG())

聚合函数如 SUM() 和 AVG() 也可以作为窗口函数使用,可以计算累计总和或移动平均值。

基本用法
SELECT 
    date,
    sales,
    SUM(sales) OVER (ORDER BY date) as cumulative_sales,
    AVG(sales) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) as moving_avg
FROM daily_sales;
实际应用场景1:计算累计总和

假设我们要计算每个部门的累计销售额:

CREATE TABLE sales (
    id INT,
    department VARCHAR(50),
    sale_date DATE,
    amount DECIMAL(10, 2)
);

INSERT INTO sales (id, department, sale_date, amount) VALUES
(1, 'Electronics', '2023-01-01', 1000),
(2, 'Clothing', '2023-01-01', 500),
(3, 'Electronics', '2023-01-02', 1500),
(4, 'Clothing', '2023-01-02', 750),
(5, 'Electronics', '2023-01-03', 1200),
(6, 'Clothing', '2023-01-03', 600);

SELECT 
    department,
    sale_date,
    amount,
    SUM(amount) OVER (
        PARTITION BY department
        ORDER BY sale_date
    ) as cumulative_sales
FROM sales
ORDER BY department, sale_date;

这个查询计算了每个部门的累计销售额,按日期排序。
在这里插入图片描述

实际应用场景2:计算移动平均值

假设我们有一个股票价格表,我们想计算7天移动平均价格:

CREATE TABLE stock_prices (
    date DATE,
    price DECIMAL(10, 2)
);

INSERT INTO stock_prices (date, price) VALUES
('2023-01-01', 100.00),
('2023-01-02', 101.00),
('2023-01-03', 102.00),
('2023-01-04', 101.50),
('2023-01-05', 103.00),
('2023-01-06', 104.00),
('2023-01-07', 103.50),
('2023-01-08', 105.00),
('2023-01-09', 106.00),
('2023-01-10', 107.00);

SELECT 
    date,
    price,
    AVG(price) OVER (
        ORDER BY date
        ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
    ) AS moving_avg
FROM stock_prices
ORDER BY date;

这个查询将计算包括当前日期在内的前7天的移动平均价格。
在这里插入图片描述

结论

窗口函数是MySQL 8.0中的一个强大新特性,可以大大简化复杂的数据分析任务。通过上述实际应用场景的例子,我们可以看到窗口函数在处理排名、时间序列数据、累计计算等方面的强大能力。这些函数使得我们能够更高效地处理诸如员工排名、同比增长、累计总和、移动平均等常见的数据分析问题。

随着对窗口函数的深入理解和熟练应用,你将能够编写更简洁、更高效的SQL查询,大大提高数据分析的效率。窗口函数不仅可以简化查询,还可以提高查询性能,因为它们通常比使用子查询或自连接的等效查询更有效率。

继续探索和实践这些窗口函数,你会发现它们在日常数据分析工作中的无穷潜力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1949129.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单元测试的最佳实践

整体架构 合适的架构可以提升可测试性。比如菱形对称架构的模块化和解耦特性使得系统各个部分可以独立进行单元测试。这不仅提高了测试的效率&#xff0c;还能够减少测试的依赖性&#xff0c;提高测试准确性。 代码设计 代码设计和可测试性有密切关联。强烈建议一个方法的代码行…

Java面试八股之什么是spring boot starter

什么是spring boot starter Spring Boot Starter是Spring Boot项目中的一个重要概念。它是一种依赖管理机制&#xff0c;用于简化Maven或Gradle配置文件中的依赖项声明。Spring Boot Starter提供了一组预定义的依赖关系&#xff0c;这些依赖关系被封装在一个单一的包中&#x…

CC-Link转Profinet协议网关功能与配置详解

怎么样才能把CC-Link和Profinet网络连接起来呢?这几天有几个朋友问到了这个问题&#xff0c;作者在这里统一为大家详细说明一下。其实有一个设备可以很轻松地解决这个问题&#xff0c;名为JM-PN-CCLK&#xff0c;下面是详细介绍。 一&#xff0c;产品主要功能 1、捷米特JM-P…

go语言学习文档精简版

Go语言是一门开源的编程语言&#xff0c;目的在于降低构建简单、可靠、高效软件的门槛。Go平衡了底层系统语言的能力&#xff0c;以及在现代语言中所见到的高级特性。 你好&#xff0c;Go package main // 程序组织成包import "fmt" // fmt包用于格式化输出数据// …

【C++_list】理解链表!实现链表!成为链表!!

List 1. list的介绍及使用2. list的模拟1&#xff09;大致了解List框架2&#xff09;模拟实现List操作3&#xff09;关于const迭代器的问题&#xff08;重点&#xff09;4&#xff09;关于链表拷贝的问题 1. list的介绍及使用 下面会给出list的文档介绍官网&#xff0c;也是本博…

Vue常用指令及其生命周期

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 目录 1.常用指令 1.1 v-bind 1.2 v-model 注意事项 1.3 v-on 注意事项 1.4 v-if / v-else-if / v-else 1.5 v-show 1.6 v-for 无索引 有索引 生命周期 定义 流程 1.常用指令 Vue当中的指令…

【OpenCV C++20 学习笔记】基本图像容器——Mat

【OpenCV C20 学习笔记】基本图像容器——Mat 概述Mat内部结构引用计数机制颜色数据格式 显式创建Mat对象使用cv::Mat::Mat构造函数矩阵的数据项 使用数组进行初始化的构造函数cv::Mat::create函数MATLAB风格的初始化小型矩阵通过复制创建Mat对象 Mat对象的输出其他普通数据项的…

软考:软件设计师 — 5.计算机网络

五. 计算机网络 1. OSI 七层模型 层次名称主要功能主要设备及协议7应用层实现具体的应用功能 POP3、FTP、HTTP、Telent、SMTP DHCP、TFTP、SNMP、DNS 6表示层数据的格式与表达、加密、压缩5会话层建立、管理和终止会话4传输层端到端的连接TCP、UDP3网络层分组传输和路由选择 三…

Spring事件机制

文章目录 一、Spring事件二、实现Spring事件1、自定义事件2、事件监听器2.1 实现ApplicationListener接口2.2 EventListener2.3 TransactionalEventListener 3、事件发布4、异步使用 三、EventBus1、事件模式2、EventBus三要素3、同步事件3.1 定义事件类3.2 定义事件监听3.3 测…

vscode回退不显示了,不方便操作

一、后退前进按钮 顶部显示&#xff0c;方便调试 <—— ——> 文件-> 首选项 -> 设置->commandcenter->勾选 Window: Title Bar Style->custom 将native —>custom

STM32是使用的内部时钟还是外部时钟

STM32是使用的内部时钟还是外部时钟&#xff0c;经常会有人问这个问题。 1、先了解时钟树&#xff0c;见下图&#xff1a; 2、在MDK中&#xff0c;使用的是HSEPLL作为SYSCLK&#xff0c;因此需要对时钟配置寄存器&#xff08;RCC_CFGR&#xff09;进行配置&#xff0c;寄存器内…

Linux:传输层(2) -- TCP协议(2)

目录 1. 流量控制 2. 滑动窗口 3. 拥塞控制 4. 延迟应答 5. 捎带应答 6. 面向字节流 7. 粘包问题 8. TCP异常情况 1. 流量控制 接收端处理数据的速度是有限的. 如果发送端发的太快 , 导致接收端的缓冲区被打满 , 这个时候如果发送端继续发送 , 就会造成丢包, 继而引…

享元模式(结构型)

目录 一、前言 二、享元模式 三、总结 一、前言 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;用于减少大量细粒度对象的内存占用。它通过共享尽可能多的相同数据来节约内存空间。 享元模式由以下角色组成&#xff1a; Flyweight&…

【OpenCV C++20 学习笔记】扫描图片数据

扫描图片数据 应用情景图像数据扫描的难点颜色空间缩减&#xff08;color space reduction&#xff09;查询表 扫描算法计算查询表统计运算时长连续内存3种扫描方法C风格的扫描方法迭代器方法坐标方法LUT方法 算法效率对比结论 应用情景 图像数据扫描的难点 在上一篇文章《基…

项目一缓存商品

文章目录 概要整体架构流程技术细节小结 概要 因为商品是经常被浏览的,所以数据库的访问量就问大大增加,造成负载过大影响性能,所以我们需要把商品缓存到redis当中,因为redis是存在内存中的,所以效率会比MySQL的快. 整体架构流程 技术细节 我们在缓存时需要保持数据的一致性所…

AHK是让任何软件都支持 Shift + 鼠标滚轮 实现界面水平滚动

目录 基本介绍 详细特点 图解安装 下载失败&#xff1f;缓慢&#xff1f; 创建并运行脚本代码&#x1f603; 新建空 xxx.ahk文件 vscode/记事本等编辑工具打开 复制并粘贴简易脚本 运行 其他问题 问题一&#xff1a;弹出无法执行此脚本 关闭脚本 基本介绍 AutoHot…

zookeeper开启SASL权限认证

目录 一、SASL介绍 二、使用 SASL 进行身份验证 2.1 服务器到服务器的身份验证 2.2 客户端到服务器身份验证 三、验证功能 一、SASL介绍 默认情况下&#xff0c;ZooKeeper 不使用任何形式的身份验证并允许匿名连接。但是&#xff0c;它支持 Java 身份验证与授权服务(JAAS)…

用户需要什么-软件的工程可用性(第一部分)01

Larry L. Constantine 著&#xff0c;Huang Yin 译 “究竟用户的需要是什么&#xff1f;”如果 Fred 作为一个程序员而不是一个心理学家时他可能会提出这 样一个问题。用户们通常需要更多&#xff0c;而开发人员似乎看上去并不能很好的领会并更好的满足他们。对于我们而言&…

WPF使用TouchSocket实现Tcp client

文章目录 前言1、页面展示2、主页面UI代码2、TCP client的UI代码3、Tcp client后台代码实现4、UI与后台代码的关联 前言 在该篇的Demo中&#xff0c;您可以找到以下内容&#xff1a; 1、TouchSocket的使用&#xff1b; 2、CommunityToolkit.Mvvm的使用&#xff1b; 3、AvalonD…

IF=8.5 MIMIC-IV高阶玩法!中国用新指标SHR+机器学习拿一区top,思路太牛了

‍ MIMIC-IV 发文难&#xff1f;那是你还没遇到对的思路&#xff01;如今机器学习数据库挖掘的文章层出不穷&#xff0c;今天介绍的这篇文章是在MIMIC-IV数据库的基础上&#xff0c;用了一个新指标—应激性高血糖比&#xff08;SHR&#xff09;&#xff0c;结合机器学习构建预测…