导读:本期聚焦于小伙伴创作的《SQL窗口函数有哪些高级应用?它为什么是数据分析的强大工具》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL窗口函数有哪些高级应用?它为什么是数据分析的强大工具》有用,将其分享出去将是对创作者最好的鼓励。

SQL窗口函数是数据分析场景下非常实用的功能,它可以在不改变原表行数的前提下,对每一行数据基于指定的窗口范围做计算,避免了传统写法中大量子查询嵌套的问题。下面我们先通过一张示意图了解窗口函数的基本逻辑,再逐步深入探讨它的高级应用。

SQL窗口函数有哪些高级应用?它为什么是数据分析的强大工具

窗口函数基础语法

窗口函数的基本语法结构如下,其中over子句就是定义窗口范围的核心部分:

-- 窗口函数基本语法
函数名(参数) over (
    [partition by 分组列1, 分组列2...]
    [order by 排序列1 [asc|desc], 排序列2 [asc|desc]...]
    [rows|range between 边界1 and 边界2]
)

其中partition by用来指定分组的列,类似group by但不会压缩行数;order by指定窗口内的排序规则;最后的边界指定用来控制窗口的计算范围,比如是计算当前行及之前的所有行,还是当前行前后几行的数据。

常见高级应用场景

1 分组排名与 Top N 查询

排名类窗口函数是使用频率最高的场景,比如要查询每个部门薪资最高的前3名员工,传统写法需要先分组计算每个部门的最高薪资再关联,而用窗口函数只需要一行计算:

-- 查询每个部门薪资前3的员工
select 
    dept_name,
    emp_name,
    salary,
    rank_num
from (
    select 
        dept_name,
        emp_name,
        salary,
        -- row_number 相同薪资会生成不同排名,rank 相同薪资排名相同后续跳过,dense_rank 相同薪资排名相同后续不跳过
        dense_rank() over (partition by dept_name order by salary desc) as rank_num
    from emp_salary
) t
where rank_num <= 3;

2 同比环比与偏移量计算

分析业务数据的增长情况时,经常需要拿当前数据和上一周期、上一年同期的数据做对比,这时候可以用laglead偏移函数,直接获取当前行之前或之后的数据:

-- 计算月度销售额的环比和同比
select 
    month_id,
    sale_amount,
    -- 取上一月的销售额,没有的话用0填充
    lag(sale_amount, 1, 0) over (order by month_id) as last_month_sale,
    -- 计算环比增长率
    round((sale_amount - lag(sale_amount, 1, 0) over (order by month_id)) / lag(sale_amount, 1, 0) over (order by month_id) * 100, 2) as mom_growth_rate,
    -- 取上一年同月的销售额
    lag(sale_amount, 12, 0) over (order by month_id) as last_year_same_month_sale,
    -- 计算同比增长率
    round((sale_amount - lag(sale_amount, 12, 0) over (order by month_id)) / lag(sale_amount, 12, 0) over (order by month_id) * 100, 2) as yoy_growth_rate
from monthly_sale;

3 移动平均与累计统计

做趋势分析时经常需要计算移动平均或者累计值,通过指定窗口的边界就能快速实现,比如计算近3个月的移动平均销售额:

-- 计算近3个月的移动平均销售额
select 
    month_id,
    sale_amount,
    -- rows between 2 preceding and current row 表示窗口包含当前行和前2行,共3行数据
    avg(sale_amount) over (order by month_id rows between 2 preceding and current row) as moving_avg_3m
from monthly_sale
where month_id >= '202401';

窗口函数对比传统写法的优势

我们可以通过一个表格直观对比两种写法的差异:

对比维度传统子查询写法窗口函数写法
代码复杂度需要多层嵌套子查询,逻辑分散单条语句完成,逻辑集中
数据粒度分组后会压缩行数,无法直接保留原表所有字段不改变原表行数,可直接关联原表其他字段
执行效率多次扫描表,性能较低一次扫描完成计算,性能更优
可维护性嵌套层级多,后期修改难度大结构清晰,修改调整方便

注意事项

  • 窗口函数只能出现在select子句和order by子句中,不能用于wheregroup by等子句
  • 排名函数和偏移函数不需要传参数,聚合函数作为窗口函数使用时需要指定聚合的列
  • 如果没有指定partition by,则整个表作为一个大的窗口进行计算
  • 边界指定中,unbounded preceding表示窗口从第一行开始,unbounded following表示窗口到最后一行结束

熟练掌握SQL窗口函数的高级应用,能大幅提升数据分析场景下的查询编写效率,减少冗余代码,是数据分析人员必备的技能之一。日常使用中可以根据具体的计算需求,灵活组合分区、排序、边界三个部分,适配不同的业务场景。

SQL窗口函数数据分析OLAP修改时间:2026-05-28 00:39:34

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。