SQL:窗口函数(Window Functions)

目录

什么是窗口函数?

基本语法结构 

为什么要用窗口函数?

常见的窗口函数分类

1️⃣ 排名类函数

2️⃣ 聚合类函数(不影响原始行)

3️⃣ 值访问函数

窗口范围说明(ROWS / RANGE)


什么是窗口函数?

窗口函数是一类 SQL 函数,在不分组的情况下,可以对查询结果中的某一“窗口”范围内的数据进行计算。

窗口函数 = 能在每一行数据上“看见”其他相关行的函数。

它允许你在不聚合(不合并行)的前提下,对一组相关行进行计算,并把结果加回到原来的每一行上。

不同于聚合函数(如 SUM, AVG),窗口函数不会压缩行,而是为每一行返回一个计算值。

基本语法结构 

<窗口函数>([参数]) OVER ([PARTITION BY 子句][ORDER BY 子句][ROWS 或 RANGE 子句]
)函数名(...) OVER (PARTITION BY ...   -- 按谁分组(可选)ORDER BY ...       -- 按什么顺序(常用)ROWS BETWEEN ...   -- 控制范围(高级用法)
)
  • PARTITION BY: 把数据分组,每组内独立执行函数(类似 GROUP BY,但不合并行)。

  • ORDER BY: 确定组内数据顺序。

  • ROWS BETWEEN: 精确控制窗口范围(例如:过去3行)。

举例:

SELECT department_id,employee_id,salary,RANK() OVER(PARTITION BY department_id ORDER BY salary DESC) AS rank_in_dept
FROM employees;

为什么要用窗口函数?

在传统的 SQL 聚合函数(如 SUM, AVG, COUNT)中,如果你写:

SELECT person_id, SUM(weight)
FROM Queue
GROUP BY person_id;

你得到的是每个 person_id 的总重,但你没法看到其他人的情况 —— 一条记录一条记录独立计算。

而窗口函数就像给每一行配了一个“望远镜”,能看到前面的、后面的或整组内的数据,然后基于这些数据算出“每一行自己的视角”。

举个通俗例子(排队上车):

有一张表:

turnperson_nameweight
1Alice250
2Bob300
3Charlie200
4David400

你想知道:每个人上车时,前面所有人(包括自己)累计多重了?

👉 用窗口函数就可以这样写:

SELECT person_name,weight,SUM(weight) OVER (ORDER BY turn) AS cumulative_weight
FROM Queue;

输出结果:

person_nameweightcumulative_weight
Alice250250
Bob300550 (250+300)
Charlie200750 (250+300+200)
David4001150

🚀 神奇的是,你没有把这些行合并,而是在每行里加上了“前面和自己的累积情况”


常见的窗口函数分类

1️⃣ 排名类函数

函数描述
ROW_NUMBER()每一组数据中按顺序分配唯一行号
RANK()同分并列,跳跃排名(如:1,1,3)
DENSE_RANK()同分不跳(如:1,1,2)
NTILE(n)将结果分为 n 个桶,每行给出所属桶编号

1.ROW_NUMBER()

意义:按顺序为每行分配一个“唯一编号”。
名称:ROW_NUMBER = 行号。

语法示例:

ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num

用途:

  • 对每个部门中员工薪资进行唯一编号(常用于分页、去重等)

2.RANK()

意义:返回排名,相同值并列排名,后续名次跳跃。
名称:RANK = 排名。

语法示例:

RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank
salaryRANK
10001
10001
9003

3.DENSE_RANK()

意义:与 RANK() 类似,但排名连续不跳跃。
名称:DENSE_RANK = 密集排名。

语法示例:

DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dense_rank
salaryDENSE_RANK
10001
10001
9002

4. NTILE(n)

意义:将数据平均分成 n 个桶,每行返回桶编号。
名称:NTILE = "N Tile",即“分桶”。

语法示例:

NTILE(4) OVER (ORDER BY salary DESC) AS quartile

用途:

  • 按工资水平将员工划分为四个档次(四分位分析)


2️⃣ 聚合类函数(不影响原始行)

函数描述
SUM(), AVG(), MAX(), MIN()聚合函数 + 窗口:在窗口范围内计算
COUNT()窗口内的行数统计

5. SUM(expr)AVG(expr)MAX(expr)MIN(expr)

意义:在窗口内执行聚合计算,但不影响原始行展示。
名称:

  • SUM = 总和

  • AVG = 平均

  • MAX = 最大值

  • MIN = 最小值

语法示例:

SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_date) AS running_total

用途:

  • 滚动汇总、组内对比等。


3️⃣ 值访问函数

函数描述
LAG(expr, n, default)返回当前行前第 n 行的值
LEAD(expr, n, default)返回当前行后第 n 行的值
FIRST_VALUE(expr)窗口中的第一个值
LAST_VALUE(expr)窗口中的最后一个值

6. LAG(expr, offset, default)

意义:返回当前行的前 N 行的值。
名称:LAG = 滞后。

语法示例:

LAG(salary, 1, 0) OVER (PARTITION BY department_id ORDER BY hire_date) AS prev_salary

用途:

  • 分析趋势、比较环比。

7. LEAD(expr, offset, default)

意义:返回当前行的后 N 行的值。
名称:LEAD = 领先。

语法示例:

LEAD(salary, 1, 0) OVER (PARTITION BY department_id ORDER BY hire_date) AS next_salary

用途:

  • 预测未来、构建时间序列对比。

 8. FIRST_VALUE(expr)

意义:返回窗口中按排序后第一行的值。
名称:FIRST_VALUE = 第一个值。

语法示例:

FIRST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY hire_date) AS first_salary

9. LAST_VALUE(expr)

意义:返回窗口中最后一行的值。
名称:LAST_VALUE = 最后一个值。

注意: LAST_VALUE 需要配合 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING 才能获取整个分区最后一行值。

LAST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY hire_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS last_salary


窗口范围说明(ROWS / RANGE)

ROWS基于物理行号

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW

 RANGE基于值范围

RANGE BETWEEN INTERVAL 7 DAY PRECEDING AND CURRENT ROW

常见用途总结

场景推荐函数
排名ROW_NUMBER, RANK, DENSE_RANK
对比趋势LAG, LEAD, FIRST_VALUE, LAST_VALUE
滚动汇总SUM, AVG, COUNT + ROWS BETWEEN
分段统计NTILE
时间窗口RANGE BETWEEN

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

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

相关文章

相机内参 opencv

视场角定相机内参 import numpy as np import cv2 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3Ddef calculate_camera_intrinsics(image_width640, image_height480, fov55, is_horizontalTrue):"""计算相机内参矩阵参数:image_w…

MATLAB 各个工具箱 功能说明

​ 想必大家在安装MATLAB时&#xff0c;或多或少会疑惑应该安装哪些工具箱。笔者遇到了两种情况——只安装了MATLAB主程序&#xff0c;老师让用MATLAB的时候却发现没有安装对应安装包&#xff1b;第二次安装学聪明了&#xff0c;全选安装&#xff0c;嗯……占用了20多个G。 ​…

学习日记-day14-5.23

完成目标&#xff1a; 学习java下半段课程 知识点&#xff1a; 1.多态转型 知识点 核心内容 重点 多态转型 向上转型&#xff08;父类引用指向子类对象&#xff09; 与向下转型&#xff08;强制类型转换&#xff09;的机制与区别 向上转型自动完成&#xff0c;向下转型需…

【编程语言】【Java】一篇文章学习java,复习完善知识体系

第一章 Java基础 1.1 变量与数据类型 1.1.1 基本数据类型 1.1.1.1 整数类型&#xff08;byte、short、int、long&#xff09; 在 Java 中&#xff0c;整数类型用于表示没有小数部分的数字&#xff0c;不同的整数类型有不同的取值范围和占用的存储空间&#xff1a; byte&am…

汇量科技前端面试题及参考答案

数组去重的方法有哪些&#xff1f; 在 JavaScript 中&#xff0c;数组去重是一个常见的操作&#xff0c;有多种方法可以实现这一目标。每种方法都有其适用场景和性能特点&#xff0c;下面将详细介绍几种主要的去重方法。 使用 Set 数据结构 Set 是 ES6 引入的一种新数据结构&a…

Git实战演练,模拟日常使用,快速掌握命令

01 引言 上一期借助Idea&#xff0c;完成了Git仓库的建立、配置、代码提交等操作&#xff0c;初步入门了Git的使用。然而日常开发中经常面临各种各样的问题&#xff0c;入门级的命令远远不够使用。 这一期&#xff0c;我们将展开介绍Git的日常处理命令&#xff0c;解决日常问…

wordpress主题开发中常用的12个模板文件

在WordPress主题开发中&#xff0c;有多种常用的模板文件&#xff0c;它们负责控制网站不同部分的显示内容和布局&#xff0c;以下是一些常见的模板文件&#xff1a; 1.index.php 这是WordPress主题的核心模板文件。当没有其他更具体的模板文件匹配当前页面时&#xff0c;Wor…

数据库blog5_数据库软件架构介绍(以Mysql为例)

&#x1f33f;软件的架构 &#x1f342;分类 软件架构总结为两种主要类型&#xff1a;一体式架构和分布式架构 ● 一体化架构 一体式架构是一种将所有功能集成到一个单一的、不可分割的应用程序中的架构模式。这种架构通常是一个大型的、复杂的单一应用程序&#xff0c;包含所…

离线服务器算法部署环境配置

本文将详细记录我如何为一台全新的离线服务器配置必要的运行环境&#xff0c;包括基础编译工具、NVIDIA显卡驱动以及NVIDIA-Docker&#xff0c;以便顺利部署深度学习算法。 前提条件&#xff1a; 目标离线服务器已安装操作系统&#xff08;本文以Ubuntu 18.04为例&#xff09…

chromedp -—— 基于 go 的自动化操作浏览器库

chromedp chromedp 是一个用于 Chrome 浏览器的自动化测试工具&#xff0c;基于 Go 语言开发&#xff0c;专门用于控制和操作 Chrome 浏览器实例。 chromedp 安装 go get -u github.com/chromedp/chromedp基于chromedp 实现的的简易学习通刷课系统 目前实现的功能&#xff…

高级特性实战:死信队列、延迟队列与优先级队列(三)

四、优先级队列&#xff1a;优先处理重要任务 4.1 优先级队列概念解析 优先级队列&#xff08;Priority Queue&#xff09;是一种特殊的队列数据结构&#xff0c;它与普通队列的主要区别在于&#xff0c;普通队列遵循先进先出&#xff08;FIFO&#xff09;的原则&#xff0c;…

python打卡day34

GPU训练及类的call方法 知识点回归&#xff1a; CPU性能的查看&#xff1a;看架构代际、核心数、线程数GPU性能的查看&#xff1a;看显存、看级别、看架构代际GPU训练的方法&#xff1a;数据和模型移动到GPU device上类的call方法&#xff1a;为什么定义前向传播时可以直接写作…

Newtonsoft Json序列化数据不序列化默认数据

问题描述 数据在序列号为json时,一些默认值也序列化了,像旋转rot都是0、缩放scal都是1,这样的默认值完全可以去掉,减少和服务器通信数据量 核心代码 数据结构字段增加[DefaultValue(1.0)]属性,缩放的默认值为1 public class Vec3DataOne{[DefaultValue(1.0)] public flo…

可增添功能的鼠标右键优化工具

软件介绍 本文介绍一款能优化Windows电脑的软件&#xff0c;它可以让鼠标右键菜单添加多种功能。 软件基本信息 这款名为Easy Context Menu的鼠标右键菜单工具非常小巧&#xff0c;软件大小仅1.14MB&#xff0c;打开即可直接使用&#xff0c;无需进行安装。 添加功能列举 它…

Gemini 2.5 Pro 一次测试

您好&#xff0c;您遇到的重定向循环问题&#xff0c;即在 /user/messaging、/user/login?return_to/user/messaging 和 /user/login 之间反复跳转&#xff0c;通常是由于客户端的身份验证状态检查和页面重定向逻辑存在冲突或竞争条件。 在分析了您提供的代码&#xff08;特别…

vue3前端后端地址可配置方案

在开发vue3项目过程中&#xff0c;需要切换不同的服务器部署&#xff0c;代码中配置的服务需要可灵活配置&#xff0c;不随着run npm build把网址打包到代码资源中&#xff0c;不然每次切换都需要重新run npm build。需要一个配置文件可以修改服务地址&#xff0c;而打包的代码…

大模型微调与高效训练

随着预训练大模型(如BERT、GPT、ViT、LLaMA、CLIP等)的崛起,人工智能进入了一个新的范式:预训练-微调(Pre-train, Fine-tune)。这些大模型在海量数据上学习到了通用的、强大的表示能力和世界知识。然而,要将这些通用模型应用于特定的下游任务或领域,通常还需要进行微调…

编程技能:字符串函数10,strchr

专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏&#xff0c;故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 &#xff08;一&#xff09;WIn32 专栏导航 上一篇&#xff1a;编程技能&#xff1a;字符串函数09&#xff0c;strncmp 回到目录…

动态规划-53.最大子数组和-力扣(LeetCode)

一、题目解析 在给定顺序的数组中找出一段具有最大和的连续子数组&#xff0c;且大小最小为1. 二、算法原理 1.状态表示 我们可以意一一枚举出所有的子数组&#xff0c;但我们想要的是最大子数组&#xff0c;所以f[i]表示&#xff1a;以i位置为结尾&#xff0c;所有子数组的最…

C++ queue对象创建、queue赋值操作、queue入队、出队、获得队首、获得队尾操作、queue大小操作、代码练习

对象创建&#xff0c;代码见下 #include<iostream> #include<queue>using namespace std;int main() {// 1 默认构造函数queue<int> q1;// 2 拷贝构造函数queue<int> q2(q1);return 0;} queue赋值操作&#xff0c;代码见下 #include<iostream>…