当前位置: 首页 > news >正文

【SQL学习笔记3】深入理解窗口函数的用法

SQL中的窗口函数(Window Functions)是一种特殊的函数,它允许在查询的结果集的行之间进行计算。与聚合函数不同的是,窗口函数不会将多行数据聚合成一行;相反,它们可以为结果集中的每一行执行计算,并返回一个值。这使得窗口函数非常适合用于需要保持原始行信息的同时进行复杂分析的场景。

常见的窗口函数包括:

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

2.RANK(): 根据ORDER BY子句指定的顺序对结果集进行排名。如果有相同的值,则它们会得到相同的排名,但会影响后续排名的编号。 

3.DENSE_RANK(): 类似于RANK(),但是当有相同排名时,DENSE_RANK()不会跳过后续的排名编号

4.NTILE(n): 将结果集划分为n个大致相等的部分,为每一行分配桶编号。

5.LAG() / LEAD(): 分别访问当前行之前或之后的指定行的数据。这对于比较当前行和前一行或后一行的数据非常有用。

6.SUM(), AVG(), MIN(), MAX() 等聚合函数也可以作为窗口函数使用,提供累计、移动平均等高级分析能力。

目录

一、创建表并插入数据

二、演示几种不同的窗口函数用法

1. ROW_NUMBER() OVER() 

2. RANK() over()

3. DENSE_RANK()

4. NTILE(n)

5.LAG() 和 LEAD() 

我们可以从零开始,创建一个简单的数据表,并插入一些示例数据,然后通过窗口函数进行演练。

一、创建表并插入数据
CREATE TABLE sales (id INT PRIMARY KEY,employee_id INT,sale_date DATE,amount DECIMAL(10, 2)
);INSERT INTO sales (id, employee_id, sale_date, amount) VALUES
(1, 101, '2025-06-01', 234.56),
(2, 102, '2025-06-02', 123.45),
(3, 101, '2025-06-03', 345.67),
(4, 103, '2025-06-04', 456.78),
(5, 102, '2025-06-05', 567.89),
(6, 101, '2025-06-06', 678.90);
二、演示几种不同的窗口函数用法
1. ROW_NUMBER() OVER() 

为每位员工的销售记录按日期排序分配一个唯一的行号。

SELECT id,employee_id,sale_date,amount,ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY sale_date) AS row_num
FROM sales;

输出示例如下:

2. RANK() over()

根据销售金额对每位员工的销售记录进行排名。如果有相同的销售金额,它们会得到相同的排名,但后续排名会跳过。

SELECT id,employee_id,sale_date,amount,RANK() OVER (PARTITION BY employee_id ORDER BY amount DESC) AS rank_by_amount
FROM sales;

3. DENSE_RANK()

RANK()类似,但如果存在相同的销售金额,它不会跳过后续的排名编号。

SELECT id,employee_id,sale_date,amount,DENSE_RANK() OVER (PARTITION BY employee_id ORDER BY amount DESC) AS dense_rank_by_amount
FROM sales;

4. NTILE(n)

将结果集划分为n个大致相等的部分,为每一行分配桶编号。这里我们将每个员工的销售记录分成两部分(即NTILE(2))。

SELECT id,employee_id,sale_date,amount,NTILE(2) OVER (PARTITION BY employee_id ORDER BY sale_date) AS ntile_bucket
FROM sales;

5.LAG() 和 LEAD() 

分别访问当前行之前或之后的指定行的数据。这对于比较当前行与前一行或后一行的数据非常有用。

使用 LAG() 查看每位员工上一笔销售的金额:

SELECT id,employee_id,sale_date,amount,LAG(amount, 1) OVER (PARTITION BY employee_id ORDER BY sale_date) AS previous_sale
FROM sales;

使用 LEAD() 查看每位员工下一笔销售的金额:

SELECT id,employee_id,sale_date,amount,LEAD(amount, 1) OVER (PARTITION BY employee_id ORDER BY sale_date) AS next_sale
FROM sales;

http://www.xdnf.cn/news/970417.html

相关文章:

  • 鹰盾加密器系统黑屏问题的深度解析与处理机制
  • RAG系统向量数据库选型与Prompt Engineering鲁棒性测试实践
  • 10:00开始面试,10:06就出来了,问的问题有点变态。。。
  • 第14篇:数据库中间件的分布式配置与动态路由规则热加载机制
  • vxe-table 如何实现直接渲染输入框控件,不需要点击编辑方式,直接就显示文本框
  • DSL查询文档
  • Android OpenSL ES 音频播放完整实现指南
  • AtCoder Beginner Contest 408
  • 电路笔记(元器件):并串转换芯片 SN65LV1023A 10:1 LVDS 串行器/解串器变送器 100 至 660Mbps
  • HarmonyOS开发:设备管理使用详解
  • shell脚本总结15:grep命令的使用方法
  • 不变性(Immutability)模式
  • 丝路幽径:穿梭于Linux多线程控制的秘境
  • 专题一_双指针_快乐数
  • LeetCode 3442.奇偶频次间的最大差值 I:计数
  • 使用分级同态加密防御梯度泄漏
  • Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:智驿AI系统(前后端源码 + 数据库 sql 脚本)
  • 实现多路视频截图预览之后上传到后台系统
  • 2025年ASOC SCI2区TOP,协同搜索框架自适应算法+多无人机巡检规划,深度解析+性能实测
  • 专题一_双指针_复写零
  • HDFS 3.4.1 集成Kerberos 实现账户认证
  • 驭码CodeRider 2.0深度测评:助力高效开发【探索化学奇妙世界】网站
  • 【靶场】xxe漏洞2
  • 黑马Mybatis
  • UE5 学习系列(三)创建和移动物体
  • MySQL事务——博主总结
  • C# Serilog 日志
  • 西电计组第四章-存储系统
  • 72道Nginx高频题整理(附答案背诵版)
  • 【Qt】显示类控件 QLabel、QLCDNumer、QProgressBar、QCalendarWidget