news 2026/4/25 6:23:22

SQL窗口函数实战:5个高频场景完整代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL窗口函数实战:5个高频场景完整代码

大家好,我是船长。今天聊一个数据分析里最容易被问到的问题:SQL窗口函数。很多人在面试的时候会被问到,但真正用过的人其实不多。今天船长把实际工作中最常用的5个场景完整代码分享出来。

01 什么是窗口函数?

先说基础概念。

普通聚合函数(如SUM、AVG、COUNT)会把多行聚合成一行。

窗口函数不一样。它保留原有行,同时给每一行加上"窗口"计算的结果。

简单说:窗口函数 = 不减少行数的聚合计算

基本语法:

SELECT 字段, 聚合函数 OVER (PARTITION BY 分组 ORDER BY 排序) FROM 表

02 场景1:计算累计销售额

这个场景太常见了。

按日期看每天的销售额,同时想知道"到这一天为止累计卖了多少钱"。

SELECT order_date, daily_sales, SUM(daily_sales) OVER ( ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_sales FROM sales_daily

关键点:

ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

意思是:从第一行到当前行。这句决定了"窗口"的范围。

03 场景2:计算同比/环比增长率

有了窗口函数,计算增长率变得很简单。

SELECT month, sales, LAG(sales, 1) OVER (ORDER BY month) AS last_month_sales, ROUND( (sales - LAG(sales, 1) OVER (ORDER BY month)) / LAG(sales, 1) OVER (ORDER BY month) * 100, 2 ) AS mom_growth_pct FROM monthly_sales

LAG函数:取当前行之前的第N行数据。这里用LAG(sales, 1)取上月销售额。

04 场景3:分组排名

按部门分组计算员工排名。

SELECT department, employee_name, sales, RANK() OVER ( PARTITION BY department ORDER BY sales DESC ) AS dept_rank FROM employee_sales

PARTITION BY:按部门分组后再排序,每个部门独立排名。

RANK():如果有并列,会跳号(1,1,3)。如果需要不跳号,用DENSE_RANK()。

05 场景4:计算移动平均值

消除数据波动,看趋势的时候特别有用。

SELECT order_date, daily_sales, ROUND( AVG(daily_sales) OVER ( ORDER BY order_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW ), 2 ) AS ma_7d FROM sales_daily

ROWS BETWEEN 6 PRECEDING AND CURRENT ROW:当前行 + 往前6行 = 7天窗口。算出来的就是7日移动平均。

06 场景5:计算留存率

这是增长分析的灵魂。

WITH first_login AS ( SELECT user_id, MIN(login_date) AS first_date FROM user_logins GROUP BY user_id ), retention AS ( SELECT fl.user_id, DATEDIFF(ul.login_date, fl.first_date) AS days_since_first FROM user_logins ul JOIN first_login fl ON ul.user_id = fl.user_id ) SELECT days_since_first, COUNT(DISTINCT user_id) AS retained_users, ROUND( COUNT(DISTINCT user_id) * 100.0 / (SELECT COUNT(DISTINCT user_id) FROM first_login), 2 ) AS retention_rate FROM retention GROUP BY days_since_first ORDER BY days_since_first

这个查询会输出每天的留存用户数和留存率。

07 常用窗口函数速查

聚合类窗口函数:

SUM() / AVG() / COUNT() / MAX() / MIN()

导航类窗口函数:

LAG(col, N) — 取前N行

LEAD(col, N) — 取后N行

排名类窗口函数:

ROW_NUMBER() — 1,2,3,4(不并列)

RANK() — 1,1,3(并列跳号)

DENSE_RANK() — 1,1,2(并列不跳号)

分布类窗口函数:

NTILE(N) — 把数据分成N组

PERCENT_RANK() — 计算百分位排名

记住:窗口函数的核心是OVER子句。理解OVER怎么用,就理解了一切。

有问题评论区见。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 6:16:49

Python 爬虫进阶技巧:正则表达式高效提取网页关键数据实战

前言 在网络数据采集领域,Python 凭借丰富的第三方库成为爬虫开发的首选语言,而正则表达式作为文本处理的核心工具,是爬虫工程师必须掌握的进阶技能。相较于 XPath、CSS 选择器等结构化解析方式,正则表达式具备极强的灵活性,无需依赖网页 DOM 结构,即可从非结构化、半结…

作者头像 李华
网站建设 2026/4/25 6:15:52

AI智能体平台VenusFactory2:零代码驱动蛋白质工程与生命科学研究

1. 项目概述:一个为生命科学从业者打造的AI智能体平台如果你是一名生物学家、生物信息学研究员,或者正在从事蛋白质工程、药物发现相关的工作,那么你很可能已经感受到了AI浪潮带来的冲击。从AlphaFold2在结构预测上的革命性突破,到…

作者头像 李华
网站建设 2026/4/25 6:15:51

LSTM时间序列数据预处理与三维输入格式详解

1. 理解LSTM网络对时间序列数据的基本要求在处理时间序列数据时,LSTM(长短期记忆网络)作为一种特殊的循环神经网络,对输入数据有着特定的格式要求。与普通的前馈神经网络不同,LSTM能够捕捉时间序列中的长期依赖关系&am…

作者头像 李华
网站建设 2026/4/25 6:14:48

教育医学类期刊速览:高影响因子SSCI期刊推荐 | 青年教师评副高优选——3 本被低估高质量教育医学类 SSCI,审稿高效、综合认可度高,闭眼可投

还在发愁教育、行为医学方向发文难? 高分顶刊内卷严重,普通期刊认可度不足,想要分区优质、审稿高效、适合晋升 / 毕业的 SSCI 这 3 本宝藏期刊一定要收藏,门槛友好、含金量十足。 Discourse-Studies in the Cultural Politics o…

作者头像 李华
网站建设 2026/4/25 6:14:47

3分钟搞定B站视频下载:解锁4K大会员画质的完整方案

3分钟搞定B站视频下载:解锁4K大会员画质的完整方案 【免费下载链接】bilibili-downloader B站视频下载,支持下载大会员清晰度4K,持续更新中 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-downloader 还在为无法离线观看B站…

作者头像 李华