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

窗口函数总结篇

一、基本语法及常见函数

SELECT column1,column2,窗口函数() OVER (PARTITION BY 分组列 ORDER BY 排序列 [ASC|DESC]ROWS/RANGE BETWEEN 起始位置 AND 结束位置) AS 别名
FROM table_name;
​分类​​函数​​作用​​典型场景​
​排名函数​ROW_NUMBER()为每行分配唯一序号(无并列)生成唯一行号
RANK()允许并列排名,跳过重复序号(如1,1,3)带并列的排名
DENSE_RANK()允许并列排名,不跳过序号(如1,1,2)连续排名
​聚合函数​SUM() OVER()计算窗口内总和累计销售额、分区求和
AVG() OVER()计算窗口内平均值移动平均、分组平均
COUNT() OVER()统计窗口内行数累计计数、分区计数
​偏移函数​LAG(column, offset)访问当前行​​之前​​的第N行数据环比增长、上期值对比
LEAD(column, offset)访问当前行​​之后​​的第N行数据预测未来值、下期值对比

二、注意事项

0. rows between and 和 range between and的语法

必须写 between and!

前一行 + 当前行RANGE BETWEEN 1 PRECEDING AND CURRENT ROW必须明确指定起始和结束点
仅前一行RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING起始和结束点相同
默认窗口(未指定范围时)等效于 RANGE UNBOUNDED PRECEDING AND CURRENT ROW从分区第一行到当前行

1.rows between and 和 range between and 的区别

 ROWS BETWEEN(基于实际物理行数的窗口)​

  • ​定义​​:通过 ​​物理行数​​ 定义窗口范围,与排序后的实际行位置直接相关。
  • ​特点​​:
    • 窗口大小固定(按行数计算)。
    • 不受列值重复或间隔影响。
SUM(sales) OVER (ORDER BY dateROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS moving_sum
datesales
2023-01-01100
2023-01-02200
2023-01-03150
2023-01-04300

结果:

datesalesmoving_sum
2023-01-01100100
2023-01-02200300
2023-01-03150450
2023-01-04300650

2. RANGE BETWEEN(基于值的窗口)​

  • ​定义​​:通过 ​​列值的逻辑范围​​ 定义窗口边界,与排序后的列值相关。
  • ​特点​​:
    • 窗口大小动态(按列值区间计算)。
    • 受列值重复或间隔影响。
SUM(sales) OVER (ORDER BY dateRANGE BETWEEN INTERVAL 2 DAY PRECEDING AND CURRENT ROW
) AS range_sum
datesales
2023-01-01100
2023-01-03200
2023-01-04150
2023-01-06

300

输出

datesalesrange_sum
2023-01-01100100
2023-01-03200300
2023-01-04150350
2023-01-06300450

例2:

SUM(sales) OVER (ORDER BY salesRANGE BETWEEN 1 PRECEDING AND  CURRENT ROW  
) AS sum_prev_only

假设窗口函数按 ORDER BY sales 排序,则 RANGE BETWEEN 1 PRECEDING AND CURRENT ROW 的窗口范围定义为:

  • ​起始点​​:当前行的 sales 值减去 1
  • ​结束点​​:当前行的 sales 值。
  • ​窗口包含所有 sales 值在区间 [当前值 -1, 当前值] 的行​​。

2.实际上 rows between 用的更多

3. 几种排名函数

在MySQL8.X或者hive中专用的窗口函数有3个:

  • rank:并列跳跃排名,相同的排名会跳过
  • dense_rank:并列连续排名 , 相同的排名不会跳过
  • row_number:连续排名 , 不管值的大小 ,都是从1,2,3,4依次排列下去(用的少)

通过一个例子来说明3个函数的排序差异体现在哪里。现在给定五个成绩:93,93,85,80,75,分别使用3个不同的开窗函数得到的结果分别是:

1、使用 DENSE_RANK() 进行排名会得到:1,1,2,3,4

2、使用 RANK() 进行排名会得到:1,1,3,4,5

3、使用 ROW_NUMBER() 进行排名会得到:1,2,3,4,5

这几种排名函数使用时必须跟着 order by , 指定依据哪一列进行排行

4.LAG() 和 Rows between 的区别

​特性​LAG()(单行偏移访问)ROWS BETWEEN(窗口范围聚合)
​功能​直接访问 ​​特定偏移行的单值​定义窗口范围,​​聚合多行数据​​(如求和、平均)
​返回值​单行的字段值聚合结果(如总和、平均值)
​操作粒度​精确访问某一行(如前1行、前2行)操作一组行的聚合值
​性能​高效(直接定位行)可能更耗资源(需遍历多行)

三、相关例题

1. LC 185

注意事项:

partition by 后面的字段必须使用表的原名!!

2.体育馆的人流量 LC 601

本题需求:

编写解决方案找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录。

思路:

1.先把人流大于100的选出来,放在那

2.要求id 连续的三行 , 可以注意到

id连续的行,它们与各自的row_number 之差都是一样的,如下所示

3.根据此 , 我们在分组统计一下rk的数量大于3的 , 就是至少3天连续的id了

4.后续就是一些繁琐的连表查询 , 慢慢写即可

代码:

with s as(select id , visit_date , people from Stadiumwhere people >= 100
)
,
temp as(
select id - row_number() over(order by id asc) diff , id , visit_date , people
from s
)
select id ,visit_date , people from temp left join (
select diff , count(diff) cnt from temp 
group by diff 
)cur on temp.diff = cur.diff
where cnt >= 3

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

相关文章:

  • -动静态库简单使用
  • ABC 352
  • 依赖倒置原则 (Dependency Inversion Principle, DIP)
  • 分块查找详解
  • 第二章 1.3 数据采集风险的现有技术和解决方案
  • RK3568 OH5.1 镜像烧录
  • python第34天打卡
  • 深耕数字化赛道,联众优车以创新风控体系构筑汽车金融护城河
  • Fine-tuning:微调技术,训练方式,LLaMA-Factory,ms-swift
  • AI智能分析网关V4垃圾桶满溢检测算法打造城市/公园/街道等场景应用方案
  • 浅谈Mysql的MVCC机制(RC与RR隔离级别)
  • LeetCode 1696. 跳跃游戏 VI(中等)
  • AI Agent开发第75课-数据、张量、流水线并行全解析
  • 【Web应用】若依:基础篇03-入门案例,若依代码生成器生成前后端代码
  • Web通信协议全景解析:从HTTP到WebService的技术演进与对比
  • 如何寻找大模型在企业业务中的价值?
  • Anaconda下载安装+配置虚拟环境保姆级教程(2025版)
  • 实时数仓flick+clickhouse启动命令
  • 第一个ASP.NET项目
  • 【Elasticsearch】retry_on_conflict
  • Python中while 1和while True有何区别?深入解析无限循环的写法选择
  • 百胜咨询公司:企业EcoVadis认证的专业导航者
  • SIGGRAPH 2025 | 快手可灵团队提出3D感知的电影级文本到视频生成框架CineMaster
  • 鸿蒙5开发宝藏案例分享---一多断点开发实践
  • 0527漏洞原理:SQL注入笔记 SQL注入类型(联合查询注入、报错注入实操)
  • 【本地部署】 Deepseek+Dify创建工作流
  • 【Vue 3 运行时 Diff 算法深度解析:五步走策略实现高效更新】
  • MySQL数据库第一章
  • 科技趋势分析系统 BBC (Big Bang of Computing)
  • mysql中的索引怎么用?