MySQL窗口函数详解

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查询,大大提高数据分析的效率。窗口函数不仅可以简化查询,还可以提高查询性能,因为它们通常比使用子查询或自连接的等效查询更有效率。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker搭建ES 8.14 集群

参考&#xff1a;【docker搭建es8集群kibana】_docker 安装生产级 es 8.14 集群-CSDN博客 1、之前已搭建一台单机版的dockerES集群 参见 Elasticsearch docker 安装_docker 安装es8.14.3-CSDN博客 2、现在需要重新搭建为docker ES集群 准备新搭建3个点 一、准备工作 提前开…

【中项】系统集成项目管理工程师-第4章 信息系统架构-4.3应用架构

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

计蒜客T3473(丑数) 优先队列,质因数,小题大做一下

文章目录 丑数思考过程代码 丑数 思考过程 其实现在这一题&#xff0c;我还没把代码敲完。但想赶紧把自己的思考过程给记录下来&#xff0c;不然一会儿&#xff0c;一些细节就捕捉不到了。因为才看了一个“广告”&#xff0c;关于抓住瞬间的灵感&#xff0c;虽然我这纯属是小儿…

分类常用的评价指标-二分类/多分类

二分类常用的性能度量指标 精确率、召回率、F1、TPR、FPR、AUC、PR曲线、ROC曲线、混淆矩阵 「精确率」查准率 PrecisionTP/(TPFP) 「召回率」查全率RecallTP/(TPFN) 「真正例率」即为正例被判断为正例的概率TPRTP/(TPFN) 「假正例率」即为反例被判断为正例的概率FPRFP/(TNFP)…

Visual Studio 2022美化

说明&#xff1a; VS版本&#xff1a;Visual Studio Community 2022 背景美化 【扩展】【管理扩展】搜索“ClaudiaIDE”&#xff0c;【下载】&#xff0c;安装完扩展要重启VS 在wallhaven下载壁纸图片作为文本编辑器区域背景图片 【工具】【选项】搜索ClaudiaIDE&#xff…

YOLOX+PyQt5交通路口智能监测平台设计与实现

1.概述 交通要道的路口上人车穿行&#xff0c;特别是上下班早高峰&#xff0c;且时常发生交通事故。因此对交通路口的车流量和人流量的监测必不可少。 2.检测模型 使用的检测模型为YOLOX模型&#xff0c;模型权重为训练VOC数据集得来&#xff0c;其中包括了二十个类别&#…

前端:Vue学习 - 购物车项目

前端&#xff1a;Vue学习 - 购物车项目 1. json-server&#xff0c;生成后端接口2. 购物车项目 - 实现效果3. 参考代码 - Vuex 1. json-server&#xff0c;生成后端接口 全局安装json-server&#xff0c;json-server官网为&#xff1a;json-server npm install json-server -…

【运算放大器】输入失调电压和输入偏置电流(2)实例计算

概述 根据上一篇文章的理论&#xff0c;分别计算没有输入电阻和有输入电阻两种情况下的运放总输出误差。例题来自于TI高精度实验室系列课程。 目录 概述实例计算 1&#xff1a;没有输入电阻实例计算 2&#xff1a;有输入电阻总结 实例计算 1&#xff1a;没有输入电阻 要求&am…

antdesgin table 组件下载成excel

文章目录 发现宝藏一、需求二、报错 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【宝藏入口】。 一、需求 原组件如下&#xff0c;需要添加下载功能 import React, { useState } from rea…

React间的组件通信

一、父传子&#xff08;props&#xff09; 步骤 父组件传递数据&#xff0c;子组件标签身上绑定属性子组件接收数据&#xff0c;props的参数 // 子组件 function Son(props) {return (<div>this is Son, {props.name}</div>) }// 父组件 function App() {const n…

通信原理-实验六:实验测验

实验六 实验测验 一&#xff1a;测验内容和要求 测试需要完成以下几个步骤&#xff1a; 配置好以下网络图&#xff1b;占总分10%&#xff08;缺少一个扣一分&#xff09;根据下面图配置好对应的IP和网关以及路由等相关配置&#xff0c;保证设备之间连通正常&#xff1b;占总…

谷粒商城实战笔记-60-商品服务-API-品牌管理-效果优化与快速显示开关

文章目录 一&#xff0c;显示状态列改为switch开关二&#xff0c;监听状态改变 首先&#xff0c;把ESLint语法检查关掉&#xff0c;因为这个语法检查过于严格&#xff0c;在控制台输出很多错误信息&#xff0c;干扰开发。 在build目录下下webpack.base.conf.js中&#xff0c;把…

matlab实验:实验六MATLAB 数值计算与符号运算

题目1&#xff1a;&#xff08;线性方程组数值求解&#xff09; 1&#xff0e; 用不同的方法求解下面方程&#xff1a;&#xff08;方程原式参考 P369 实验 10&#xff0c;第 1 题&#xff09; 第 1 种&#xff0c;左除和求逆函数(inv) 第 2 种 &#xff0c; 用 符 号 运 算 的…

鸿蒙(HarmonyOS)自定义Dialog实现时间选择控件

一、操作环境 操作系统: Windows 11 专业版、IDE:DevEco Studio 3.1.1 Release、SDK:HarmonyOS 3.1.0&#xff08;API 9&#xff09; 二、效果图 三、代码 SelectedDateDialog.ets文件/*** 时间选择*/ CustomDialog export struct SelectedDateDialog {State selectedDate:…

数据结构和算法入门

1.了解数据结构和算法 1.1 二分查找 二分查找&#xff08;Binary Search&#xff09;是一种在有序数组中查找特定元素的搜索算法。它的基本思想是将数组分成两半&#xff0c;然后比较目标值与中间元素的大小关系&#xff0c;从而确定应该在左半部分还是右半部分继续查找。这个…

Hyperledger Fabric 网络体验 - 网络启动过程概览

进入fabric-samples/test-network目录&#xff0c;执行指令&#xff1a; ./network.sh up -i 2.5执行完指令能看到fabric已经启动。 作为第一次Fabric网络体验&#xff0c;网络启动主要包含三个操作&#xff0c;分别是生成配置文件、启动网络和操作网络。 配置文件 使用cr…

数驭未来,景联文科技构建高质大模型数据库

国内应用层面的需求推动AI产业的加速发展。根据IDC数据预测&#xff0c;预计2026年中国人工智能软件及应用市场规模会达到211亿美元。 数据、算法、算力是AI发展的驱动力&#xff0c;其中数据是AI发展的基石&#xff0c;中国的数据规模增长速度预期将领跑全球。 2024年《政府工…

部署jar包遇到“zip file closed”和“ JCE cannot authenticate the provider BC”

一&#xff1a;导致原因 1、是因为自己打包时使用的jdk8而后运行时使用的是jdk17&#xff0c;jdk版本不一致导致的文件类型异常 二&#xff1a;报错截图 三&#xff1a;解决问题 1、使用jdk几打包就使用jdk几运行&#xff0c;列如我使用的是jdk8打包&#xff0c;使用jdk8运行…

甲方怒斥!!!为什么媒体不按原稿发布?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 前几天执行了一个媒体邀约的项目&#xff0c;邀约媒体参会&#xff0c;以及活动现场一切都很顺利&#xff0c;稿件同步的很晚&#xff0c;但还是让几个媒体连夜进行了刊登报道&#xff0…