SQL 中的 Window Function:数据分析优化技巧

发布: (2026年5月9日 GMT+8 10:54)
5 分钟阅读
原文: Dev.to

Source: Dev.to

Cover image for Master Window Function trong SQL: Bí Kíp Tối Ưu Phân Tích Dữ Liệu

大家好,数据和后端的同事们!在使用 SQL 时,大家一定都已经非常熟悉 GROUP BY。虽然功能强大,但 GROUP BY 有一个致命的缺点:它会把行“合并”,导致丢失原始数据每行的细节。

如果老板要求:“把每个订单的详细信息以及当月的总收入放在同一行”,该怎么办?这时 Window Function(窗口函数) 就大显身手了!

1. Window Function 是什么?

Window Function 允许对与当前行相关的一组行(称为“窗口”)进行计算,且不改变返回的行数

基本结构

为了让 SQL 知道你正在使用 Window Function,必须使用 OVER() 子句。OVER() 中通常包含:

  • PARTITION BY – 将数据划分为组(类似 GROUP BY,但不合并行)。
  • ORDER BY – 在每个组内对数据进行排序。
  • ROWS / RANGE – 定义更窄的窗口框架(例如:仅计算最近 3 行的总和)。

2. 平滑窗口函数类型

A. 聚合窗口函数(Aggregate Window Functions)

仍然是 SUMAVGCOUNTMAXMIN,但与 OVER() 一起使用。

示例:计算全年每日累计收入总额

SELECT
    MaDonHang,
    NgayDatHang,
    TongTien,
    SUM(TongTien) OVER (
        PARTITION BY YEAR(NgayDatHang)
        ORDER BY NgayDatHang
    ) AS TongLuyKeNam
FROM DonHang;

B. 排名窗口函数(Ranking Window Functions)

用于查找“Top N”产品、优秀员工等场景。

函数描述
ROW_NUMBER()连续编号 1, 2, 3, …(不考虑值相同的情况)。
RANK()值相等时排名相同,但会跳过后续排名(例如:1, 2, 2, 4)。
DENSE_RANK()值相等时排名相同,不跳过后续排名(例如:1, 2, 2, 3)。

示例:对每个类别的畅销产品进行排名

SELECT
    DanhMuc,
    TenSanPham,
    TongSoLuongBan,
    RANK() OVER (
        PARTITION BY DanhMuc
        ORDER BY TongSoLuongBan DESC
    ) AS HangSanPham
FROM SanPhamBanChay;

C. 值窗口函数(Value Window Functions)

获取相对于当前行的前一行或后一行的值——对计算环比、同比等波动非常有用。

  • LAG() – 获取前一行的值。
  • LEAD() – 获取后一行的值。

示例:比较本月与上月的销售额

SELECT
    Thang,
    DoanhSo,
    LAG(DoanhSo, 1, 0) OVER (ORDER BY Thang) AS DoanhSoThangTruoc,
    DoanhSo - LAG(DoanhSo, 1, 0) OVER (ORDER BY Thang) AS ChenhLech
FROM BaoCaoDoanhSo;

3. 性能优化技巧

  • Index 是关键 – 确保在 PARTITION BYORDER BY 中使用的列已经建立了合适的索引;否则 DB 将不得不手动排序,消耗资源。
  • 限制过宽的窗口帧 – 在大数据集上避免使用 UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING,除非确实需要。
  • 结合 CTE (WITH ... AS) – 当需要多个复杂的 Window Function 时,使用 CTE 将其拆分,可使代码更易阅读,且 DB 能够更好地优化 Execution Plan。

🎯 总结

与其编写冗长且运行缓慢的子查询,窗口函数提供了简洁的语法和卓越的执行速度。对于数据分析或后端报表处理等工作,这是一项必备技能。


进一步探索: 如果想练习 SQL 题目、优化查询或进行数据库设计,欢迎访问博客 ITPrep,立即提升你的技能!

来源参考:ITPrep – 窗口函数在 SQL 中的深度指南*

0 浏览
Back to Blog

相关文章

阅读更多 »