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 departmentORDER BY salary DESC) as salary_rankFROM 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 departmentORDER 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 dateROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS moving_avg
FROM stock_prices
ORDER BY date;

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

结论

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

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

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

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

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

相关文章

git 版本回退-idea

1、选中项目&#xff0c;右键&#xff0c;打开 git历史提交记录 2、选中想要回退的版本&#xff0c;选择 hard&#xff08;不保留版本记录&#xff09; 3、最终选择强制提交&#xff08;必须强制&#xff09; OK&#xff0c;搞定

AI(Adobe lliustrator)教程+软件包

简介&#xff1a; 软件主要应用于印刷出版、海报书籍排版、专业插画、多媒体图像处理和互联网页面的制作等&#xff0c;也可以为线稿提供较高的精度和控制&#xff0c;适合生产任何小型设计到大型的复杂项目。 通常用于创建LOGO(商标或徽标)&#xff0c;图标&#xff0c;插图…

go语言学习文档精简版

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

C++ primer plus 第16章string 类和标准模板库, 函数符概念

C primer plus 第16章string 类和标准模板库, 函数符概念 C primer plus 第16章string 类和标准模板库, 函数符概念 文章目录 C primer plus 第16章string 类和标准模板库, 函数符概念16.5.1 函数符概念程序清单16.15 functor.cpp 16.5.1 函数符概念 正如 STL定义了容器和迭代…

20240725项目的maven环境报红-重新配置maven

1.在编辑器里面打开项目&#xff0c;导入源码 &#xff08;1&#xff09;找到项目的地址C:\Users\zzz\IdeaProjects\datasys&#xff0c;然后右击用idea编辑器打开。 &#xff08;2&#xff09;idea中上菜单栏打开open&#xff0c;然后输入file&#xff0c;选择源代码文件 2.…

C++ //练习 15.28 定义一个存放Quote对象的vector,将Bulk_quote对象传入其中。计算vector中所有元素总的net_price。

C Primer&#xff08;第5版&#xff09; 练习 15.28 练习 15.28 定义一个存放Quote对象的vector&#xff0c;将Bulk_quote对象传入其中。计算vector中所有元素总的net_price。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块&am…

openFeign配置okhttp

原来的项目出现了性能问题&#xff0c;老大不知道怎么的&#xff0c;让我改openFeign线程池为okhttp&#xff0c;说原生的不支持线程池性能比较差。 原openFeign配置文章地址 一、pom文件 <dependency><groupId>org.springframework.cloud</groupId><arti…

泰金新能估值暴增之谜:研发费用率远低同行,资产负债率居高不下

《港湾商业观察》施子夫 王璐 作为新“国九条”首家受理的科创板IPO企业&#xff0c;外界对于西安泰金新能科技股份有限公司&#xff08;以下简称&#xff0c;泰金新能&#xff09;的关注度自然相当之高。 泰金新能保荐机构为中信建投。通过招股书不难看出&#xff0c;公司的…

idea中导入外部依赖并打包到jar包中

前言&#xff1a; 很多时候在我们写项目对接三方的时候都需要导入三方jar包&#xff0c;而这时候我们用平常的pom里面写依赖发现导入不了&#xff08;直接把jar包放在本地导入的话打包的话也不会将该依赖打包进我们项目的jar包&#xff09;&#xff0c;我在网上找了几种方法 …

使用双指针法解决最大容积问题:移动较短的线以优化面积【双指针】

在解决算法问题时&#xff0c;我们常常需要寻找最佳的方法来提高效率。今天&#xff0c;我们将讨论一个经典的问题——在一组垂直线中找到两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。这篇文章将详细解析如何使用双指针法来解决这个问题&#xff0c;特别…

仪器校准中,标准样品要怎么选用?需要注意什么?

正确使用标准物质和标准样品是保证仪器校准值准确可靠的重要手段。标准物质的正确使用包括正确选择、正确使用&#xff08;防止误用&#xff09;和使用中的注意事项。 1. 参考资料证书之中给出的“参考资料的使用”信息&#xff0c;用户应予以注意。当参比材料用于证书所述用途…

自研点直播转码核心

1. 背景 视频转码是将视频文件经过解封装、解码、滤镜处理、编码、封装从而转换为另一个视频文件的过程&#xff0c;B站每天都有大量的视频原片上传后经过转码系统转换为多个不同分辨率。转换后的视频在画质接近原片的前提下会拥有更低的码率&#xff0c;因此会提高网络传输时的…

未来的智能农业:智能合约如何提升农业生产效率和可持续性

随着全球人口的增长和资源的有限性&#xff0c;农业生产面临着越来越大的挑战。如何在提高生产效率的同时保障可持续发展成为全球农业发展的关键问题。智能合约作为一种基于区块链技术的自动化执行合约&#xff0c;正在逐渐应用于农业领域&#xff0c;为农业生产带来了新的机遇…

Leetcode刷题-----移动零283复写零问题1089

目录 1.问题介绍 1.1题目要求 1.2思路分析 1.3想法实现 2.复写零问题 2.1问题分析 2.2思路分析 2.3想法实现 1.问题介绍 1.1题目要求 把这个数组里面为0的元素挪动到这个数组的后面&#xff0c;其他的非零元素的相对位置保持不变&#xff1b; 1.2思路分析 这个里面&a…

甄选范文“论软件测试中缺陷管理及其应用”软考高级论文,系统架构设计师论文

论文真题 软件缺陷指的是计算机软件或程序中存在的某种破坏正常运行能力的问题、错误,或者隐藏的功能缺陷。缺陷的存在会导致软件产品在某种程度上不能满足用户的需要。在目前的软件开发过程中,缺陷是不可避免的。软件测试是发现缺陷的主要手段,其核心目标就是尽可能多地找…

场外期权如何报价?名义本金是什么?

今天带你了解场外期权如何报价&#xff1f;名义本金是什么&#xff1f;投资者首先需要挑选自己想要进行期权交易的沪深上市公司股票。选出股票后&#xff0c;需要将股票信息、预期的操作时间&#xff08;如期限&#xff09;、看涨或看跌的选择以及预计的交易金额等信息报给场外…

Cisco OSPF LSA 类型详解指南

注&#xff1a;机翻&#xff0c;未校对。 OSPF LSA Types: The Ultimate Guide OSPF LSA Types – OSPF LSA 类型 – OSPF uses LSAs or Link state Advertisements to share information of each network and populate the LSDB (Link State Database). The LSAs are used by…

ppt模板如何制作?5个工具让你事半功倍

让我瞧瞧是谁还在为寻找PPT模板而发愁&#xff1f; 其实这可不是什么难题~身为职场高效打工人的我&#xff0c;今天便特地为大家整理了5大ppt模板ai生成神器~想知道都有哪些选择吗&#xff1f;接着往下看你便清楚啦&#xff01; ✮迅捷PPT ☺使用场景&#xff1a;商业演示、教…

dsp c6657 SYS/BIOS学习笔记

1 SYS/BIOS简介 SYS/BIOS是一种用于TI的DSP平台的嵌入式操作系统&#xff08;RTOS&#xff09;。 2 任务 2.1 任务调度 SYS/BIOS任务线程有0-31个优先级&#xff08;默认0-15&#xff0c;优先级0被空闲线程使用&#xff0c;任务最低优先级为1&#xff0c;最高优先级为15&am…