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

SQL 实战:窗口函数的妙用 – 分析排名与分组聚合

在复杂的数据分析和查询场景中,SQL 窗口函数(Window Functions)是提升性能和代码可读性的重要工具。窗口函数可以轻松实现排名、分组聚合、滑动平均等复杂计算,避免使用嵌套子查询或冗余的多次表扫描。

本文将通过实战案例,深入剖析窗口函数的应用场景,重点讲解如何进行排名分组聚合操作。


一、窗口函数简介

1. 窗口函数的定义

窗口函数在 SQL 查询中,允许在返回的结果集中基于当前行的前后多行进行计算。窗口函数不会折叠行,而是返回每一行数据,同时增加一个聚合结果列。

2. 基本语法
SELECT 列名, 窗口函数() OVER (
    PARTITION BY 分区列 
    ORDER BY 排序列
) AS 新列名
FROM 表名;

关键词解释

  • OVER:指定窗口函数的作用范围。
  • PARTITION BY:对数据进行分区,每个分区独立计算窗口函数。
  • ORDER BY:指定窗口内的排序方式。

二、常见窗口函数

窗口函数作用说明示例
ROW_NUMBER()为每个分区内的记录生成唯一递增的编号每个部门员工的排名
RANK()生成排名,相同值时排名相同,跳过后续名次产品销量排名
DENSE_RANK()类似 RANK,不跳过名次学生成绩排名
NTILE(n)将分区内数据分为 n 份将订单分为 4 个季度
SUM()计算窗口内的累计和销售额累计和
AVG()计算窗口内的平均值滑动窗口的平均分
LAG()取当前行的前 N 行值计算上一天的销售额
LEAD()取当前行的后 N 行值计算下一季度的销售目标

三、实战案例分析

案例 1:销售排名分析

需求:获取每个地区的销售员销售额排名,排名相同销售额相等,且不跳名次。

表结构 sales

sales_idregionemployeeamount
1EastAlice1000
2EastBob1200
3WestCarol1500
4EastDavid1200
5WestEve1500

SQL 实现

SELECT 
    region,
    employee,
    amount,
    DENSE_RANK() OVER (PARTITION BY region ORDER BY amount DESC) AS rank
FROM sales;

结果

regionemployeeamountrank
EastBob12001
EastDavid12001
EastAlice10002
WestCarol15001
WestEve15001

解释

  • DENSE_RANK() 在相同金额时,给予相同的排名,不会跳过排名。
  • 每个分区(region)内独立计算排名,便于细粒度的数据分析。

案例 2:计算累计销售额(滑动窗口)

需求:计算每个地区销售额的累计和(按销售日期顺序)。

表结构 sales_history

sales_idregionemployeeamountsale_date
1EastAlice10002023-01-01
2EastBob12002023-01-05
3WestCarol15002023-01-10
4EastDavid5002023-01-12
5WestEve7002023-01-15

SQL 实现

SELECT 
    region,
    employee,
    amount,
    SUM(amount) OVER (PARTITION BY region ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_sum
FROM sales_history;

结果

regionemployeeamountcumulative_sum
EastAlice10001000
EastBob12002200
EastDavid5002700
WestCarol15001500
WestEve7002200

解释

  • SUM() OVER 计算累计和,UNBOUNDED PRECEDING 表示从窗口的第一行到当前行进行累加。
  • 每个分区(region)内,销售额随着日期递增进行累计。

案例 3:比较当前销售额与上一期销售额

需求:在销售记录表中,计算每个销售员与上一笔订单的销售额差异。

SQL 实现

SELECT 
    employee,
    amount,
    LAG(amount, 1, 0) OVER (PARTITION BY employee ORDER BY sale_date) AS previous_amount,
    amount - LAG(amount, 1, 0) OVER (PARTITION BY employee ORDER BY sale_date) AS amount_diff
FROM sales_history;

结果

employeeamountprevious_amountamount_diff
Alice100001000
Bob120001200
David5000500

解释

  • LAG() 返回当前行的前一行数据,1 表示上一行,0 表示如果没有数据则返回默认值 0
  • 计算当前销售额与上一笔订单的差异,方便追踪销售趋势。

四、窗口函数的应用场景

  1. 排名分析:计算每个部门或地区内员工的销售排名。
  2. 分组累计和:按地区或类别计算累计销量或累计收入。
  3. 同比环比分析:计算每个季度或月份与上期的差异。
  4. 移动平均与滑动窗口:计算滑动平均分或销售额,平滑波动数据。

五、总结

  • 窗口函数在 SQL 查询中极大简化了复杂的分组和排名计算,避免了繁琐的嵌套子查询。
  • 合理使用窗口函数可以显著提升 SQL 查询性能,减少冗余计算,提升数据分析效率。
  • 在日常开发中,掌握窗口函数的妙用,能让复杂的业务需求实现更加优雅、高效。

http://www.kler.cn/a/450941.html

相关文章:

  • 单机游戏《野狗子》游戏运行时提示dbghelp.dll缺失是什么原因?dbghelp.dll缺失要怎么解决?
  • 【python高级】342-TCP服务器开发流程
  • Scala项目(图书管理系统)
  • C#代码实现把中文录音文件(.mp3 .wav)转为文本文字内容
  • CNN和Transfomer介绍
  • sqlite3,一个轻量级的 C++ 数据库库!
  • 07-01-指针与数组
  • OneCode:开启高效编程新时代——企业定制出码手册
  • component-后端返回图片(数据)前端进行复制到剪切板
  • 008 Qt_显示类控件_QLabel
  • 【es6复习笔记】集合Set(13)
  • MongoDB 更新文档
  • Mac M1使用pip3安装报错
  • C++软件设计模式之装饰器模式
  • 创建仓颉编程语言的第一个项目
  • 【2024】Merry Christmas!一起用Rust绘制一颗圣诞树吧
  • GAMES101:现代计算机图形学入门-笔记-11
  • 数据结构与算法Python版 散列与区块链
  • 前端常用算法集合
  • HTTP—01
  • MQTT协议在树莓派上的安全性和性能测试及其在物联网应用中的应用
  • 【网络云计算】2024第52周-每日【2024/12/24】小测-理论实操-解析
  • docker 安装minio
  • SpringBoot的Thymeleaf做一个可自定义合并td的pdf表格
  • LeetCode33题:搜索旋转排序数组(原创)
  • 【VMware虚拟机】安装win10系统教程双机可ping通