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.rhkb.cn/news/494847.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌浏览器的网络安全检测工具介绍

作为全球最受欢迎的浏览器之一,谷歌浏览器不仅提供了快速、便捷的浏览体验,还内置了一系列强大的网络安全检测工具,帮助用户识别潜在的网络威胁,保护个人隐私和数据安全。本文将详细介绍谷歌浏览器中的几项关键网络安全检测功能&a…

一个比RTK或redux更轻量级更易使用的 React 第三方状态管理工具库的配置与使用

本文由作者 Samdy_Chan 原创,未经作者同意,请勿随意转载! 使用轻量级第三方的 React 状态管理库 zustand 管理共享状态数据 在 react 框架应用中,开发者应该大多数都是采用 redux 状态管理工具库来管理应用的共享状态数据,但用过 redux 的人都知道,其配置和使用相当复杂…

菜鸟带新鸟——基于EPlan2022的部件库制作

首先,我们需要了解一些概念: Eplan的部件制作内容 以上内容是制作一个完整的部件所需要的。如果公司要求没有那么严格,我们就可以制作1-4级的内容就可以满足日常的使用啦! 部件的创建方式 部件创建方式有4类: 1、单…

Charles安装证书过程(手机)

背景:使用模拟器抓包时,发现https请求无法抓取,需要安装相应证书。我自己是因为模拟器升级了安卓7,发现之前安装的证书无效了,需要重新安装。 参考博客:夜神模拟器12Charles进行Https抓包_模拟器抓包ssl-C…

Windows、CentOS环境下搭建自己的版本管理资料库:GitBlit

可以搭建属于公司内部或者个人的Git服务器,方便程序代码及文档版本管理。 官网:http://www.gitblit.com/ Windows环境下安装 提前已经安装好了JDK。 官网下载Windows版的GitBlit。 将zip包解压到自己想要放置的文件夹下。 建立版本库路径&#xff0c…

数据库操作【JDBC HIbernate Mybatis】

JDBC JDBC编程 在java开发中,以前都是通过JDBC(Java Data Base Connectivity)与数据库打交道的,至少在ORM(Object Relational Mapping)框架没出现之前是这样,目前常用的ORM框架有JPA、hibernat…

Linux 常见用例汇总

注:本文为 Linux 常见用例文章合辑。 部分内容已过时,未更新整理。 检查 Linux 上的 glibc 版本 译者:joeren | 2014-11-27 21:33 问:检查 Linux 系统上的 GNU C 库(glibc)的版本? GNU C 库&…

web-密码安全口令

目录 一、密码安全概述 二、密码安全现状 三、破解方式 四、暴力破解 五、字典破解 六、密码字典 学习心得: 一、密码安全概述 现在很多地方都是以用户名(账号)和口令(密码)作为鉴权的方式,口令&am…

工控触摸屏用winForms来构建框架,效果还是很不错的

工控触摸屏采用 winForms 构建框架具有诸多优势。winForms 提供了丰富的控件和强大的开发工具,使得界面设计更加高效。它具有良好的稳定性和兼容性,能够适应工控环境的复杂要求。通过 winForms 可以实现直观的操作界面,方便操作人员进行监控和…

开发一个DApp项目:DeFi、DApp开发与公链DApp开发

随着区块链技术的快速发展,去中心化应用(DApp)逐渐成为创新技术的核心之一。DApp能够利用区块链去中心化的特点,提供更高的安全性、透明性和效率,吸引了越来越多的开发者和投资者关注。本文将围绕如何开发一个DApp项目…

网络下载ts流媒体

网络下载ts流媒体 查看下载排序合并 很多视频网站,尤其是微信小程序中的长视频无法获取到准确视频地址,只能抓取到.ts片段地址,下载后发现基本都是5~8秒时长。 例如: 我们需要将以上地址片段全部下载后排序后再合成新的长视频。 …

性能优化!突破性能瓶颈的尖兵CPU Cache

缓存这个专业术语,在计算机世界中是经常使用到的。它并不是CPU所独有的,比如cdn缓存网站信息,浏览器缓存网页的图像视频等,但本文讲述的是狭义Cache,主要指的是CPU Cache,本文将其简称为"缓存"或…

Redis+注解实现限流机制(IP、自定义等)

简介 在项目的使用过程中,限流的场景是很多的,尤其是要提供接口给外部使用的时候,但是自己去封装的话,相对比较耗时。 本方式可以使用默认(方法),ip、自定义参数进行限流,根据时间…

010 Qt_输入类控件(LineEdit、TextEdit、ComboBox、SpinBox、DateTimeEdit、Dial、Slider)

文章目录 前言一、QLineEdit1.简介2.常见属性及说明3.重要信号及说明4.示例一:用户登录界面5.示例二:验证两次输入的密码是否一致显示密码 二、TextEdit1.简介2.常见属性及说明3.重要信号及说明4.示例一:获取多行输入框的内容5.示例二&#x…

RabbitMQ 的7种工作模式

RabbitMQ 共提供了7种⼯作模式,进⾏消息传递,. 官⽅⽂档:RabbitMQ Tutorials | RabbitMQ 1.Simple(简单模式) P:⽣产者,也就是要发送消息的程序 C:消费者,消息的接收者 Queue:消息队列,图中⻩⾊背景部分.类似⼀个邮箱,可以缓存消息;⽣产者向其中投递消息,消费者从其中取出消息…

WebAPI编程(第一天,第二天)

WebAPI编程(第一天,第二天) day01 - Web APIs 1.1. Web API介绍 1.1.1 API的概念1.1.2 Web API的概念1.1.3 API 和 Web API 总结 1.2. DOM 介绍 1.2.1 什么是DOM1.2.2. DOM树 1.3. 获取元素 1.3.1. 根据ID获取1.3.2. 根据标签名获取元素1.3.…

java如何使用poi-tl在word模板里渲染多张图片

1、poi-tl官网地址 http://deepoove.com/poi-tl/ 2、引入poi-tl的依赖 <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version></dependency>3、定义word模板 释义&#xf…

web三、 window对象,延时器,定时器,时间戳,location对象(地址),本地存储-localStorage,数组去重new Set

一、window对象 window对象 是一个全局对象&#xff0c;也可以说是JavaScript中的 顶级对象 像document、alert()、console.log()这些都是window的属性&#xff0c;基本BOM的属性和方法都是window的 所有通过 var定义 在全局作用域中的 变量 、 函数 都会变成window对象的属…

利用Spring Cloud Gateway Predicate优化微服务路由策略

利用Spring Cloud Gateway Predicate优化微服务路由策略 一、Predicate简介 Spring Cloud Gateway 是 Spring 生态系统中用于构建 API 网关的框架&#xff0c;它基于 Project Reactor 和 Netty 构建&#xff0c;旨在提供一种高效且灵活的方式来处理 HTTP 请求和响应。 Spring …

C#代码实现把中文录音文件(.mp3 .wav)转为文本文字内容

我们有一个中文录音文件.mp3格式或者是.wav格式&#xff0c;如果我们想要提取录音文件中的文字内容&#xff0c;我们可以采用以下方法&#xff0c;不需要使用Azure Speech API 密钥注册通过离线的方式实现。 1.首先我们先在NuGet中下载两个包 NAudio 2.2.1、Whisper.net 1.7.3…