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

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

时间:2024-12-24 12:29:44浏览次数:13  
标签:妙用 窗口 函数 amount 分组 计算 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 查询性能,减少冗余计算,提升数据分析效率。
  • 在日常开发中,掌握窗口函数的妙用,能让复杂的业务需求实现更加优雅、高效。

标签:妙用,窗口,函数,amount,分组,计算,SQL,排名
From: https://blog.csdn.net/u012561308/article/details/144690727

相关文章

  • Java 实战项目:Spring Boot + MyBatis Plus + MySQL + Shiro + Thymeleaf 赋能仓库管理
    1.项目概述本仓库管理系统旨在实现对仓库中商品、供应商、客户、员工、权限、日志等信息的有效管理,提升仓库运营效率和管理水平。系统主要功能包括基础数据管理、进货管理、销售管理、库存管理、系统管理等。2.系统架构2.1技术选型后端:SpringBoot+MyBatisPlus+MySQL......
  • elasticsearch修改Ik分词器源码实现基于MySQL更新分词
    本文主要记录如何修改Ik分词器源码来实现基于MySQL数据库更新分词,所有步骤均为本人实际操作验证。如果你也刚好刷到这篇文章,希望对你有所帮助。使用过Ik分词器的应该都知道,它提供了三种配置热词词库的方式:Ik内置词库Ik外置静态词库Ik远程词库具体可以去看Ik的配置文件,这里不......
  • mysql 分区总结
    初稿摘录,后续会按自己经验更新:https://blog.csdn.net/weixin_42507868/article/details/113294679四种常见的分区类型: RANGE分区:最为常用,基于属于一个给定连续区间的列值,把多行分配给分区。最常见的是基于时间字段。LIST分区:LIST分区和RANGE分区类似,区别在于LIST是枚举值列表......
  • Java 项目实战:全方位解析基于 Spring Boot、MySQL、FastJSON、MyBatis - Plus、Swagge
    1.引言1.1编写目的本设计文档详细阐述了SNS系统的架构、功能模块、数据结构、接口设计以及系统部署等方面,为系统的开发、测试、维护提供全面的指导,确保项目团队成员对系统有清晰一致的理解,保证系统的顺利实施与迭代优化。1.2适用范围本设计文档适用于SNS系统的开发团队、测试......
  • MySQL主从复制中启用GTID(全局事务标识符)模式
    在MySQL中启用GTID(全局事务标识符)模式进行主从复制涉及几个步骤。GTID为每个事务赋予一个唯一的标识符,从而简化了复制过程和故障恢复。以下是启用GTID模式的基本步骤:首先确保两台数据库目前数据保持一致1.准备工作确保您使用的MySQL版本支持GTID。GTID从MySQL5.6版本开始支持......
  • Can't connect to local MySQL server through socket
    mysql-urootERROR2002(HY000):Can'tconnecttolocalMySQLserverthroughsocket'/tmp/mysql.sock'(2)这是mysql登录时找不到套接字的问题。首先需要明白的是,Linux端的mysqlserver启动时会开启一个socket,Linux上的MySQL的客户端在不使用IP连接时mysqlserver时,默认......
  • PostgreSQL 的特点
    title:PostgreSQL的特点date:2024/12/24updated:2024/12/24author:cmdragonexcerpt:PostgreSQL是当今最流行的开源关系型数据库之一,凭借其优秀的性能、稳定性和丰富的功能集在用户群中享有极高声誉。相比于其他关系型数据库管理系统,PostgreSQL拥有许多独特的特点,使其......
  • 处理MYSQL 插入数据时主键相同的场景:新增?替换?忽略?
    在MySQL中,如果你尝试插入一条记录,其主键(或唯一约束字段)与已有记录的主键相同,会根据不同的操作方式产生不同的结果。以下是常见情况及其处理方式:1.使用INSERT语句如果你使用标准的INSERT语句并尝试插入一条记录,但其主键与已存在的记录冲突,会出现错误,通常是类似以下的错误......
  • mysql语句
    常用语句--检查并删除已存在的数据库DROPDATABASEIFEXISTS`date_time_test`;--创建数据库CREATEDATABASE`date_time_test`;--使用新创建的数据库USE`date_time_test`;--检查并删除已存在的表DROPTABLEIFEXISTSsales_orders;--创建表CREATETABLEsales_order......
  • php+html+mysql实现购物商城在线购物系统零食购物系统计算机源码获取php+mysql电子商
     一.功能介绍用户前台功能:前台主要包括网站首页、今日特卖、限时打折、商品中心、常见问题、我的购物车、登录、注册、商品详情,联系卖家,加入购物车、结算、个人中心等功能模块。今日特卖、限时打折、商品中心模块,用户可以查看全部商品信息,选择商品进行添加购物车等操作;购......