1. sum() + over()  做组内数据累加

       在 SQL 中想实现不同分组内数据累加,可以通过 sum() + over() PARTITION BY + ORDER BY  结合实现。这种方式能同时满足多维度分组且组内累加的需求,示例如下:

假设我们有一张 sales 表,表中存储着不同区域、不同产品的每日销售额,数据如下:

sale_idregionproductsale_dateamount
1华北手表2023-10-021000
2华北手表2023-10-031500
3华北平板2023-10-023000
4华东手表2023-10-033000
5华东手表2023-10-033500
6华东平板2023-10-034000

需求:按 region(区域)和 product(产品)分组,在每个分组内按时间顺序累加金额。

实现方法:SUM()+OVER()+PARTITION BY+ORDER BY

SELECT sale_id,region,product,sale_date,amount,-- 按区域和产品分组,组内按日期排序累加金额SUM(amount) OVER (PARTITION BY region, product  -- 多列分组:区域+产品ORDER BY sale_date            -- 组内按日期排序ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW  -- 累加范围:从组内第一条到当前行) AS cumulative_amount
FROM sales
ORDER BY region, product, sale_date;

结果:

sale_id | region  | product | sale_date  | amount | cumulative_amount
---------|---------|---------|------------|--------|------------------
1       | 华北    | 手表    | 2023-10-02 | 1000   | 1000     -- 华北手表:1000
2       | 华北    | 手表    | 2023-10-02 | 1500   | 2500     -- 华北手表:1000+1500
3       | 华北    | 手表    | 2023-10-03 | 3000   | 5500     -- 华北手表:1000+1500+3000
4       | 华东    | 手表    | 2023-10-03 | 3500   | 9000     -- 华东手表:1000+1500+3000+3500
5       | 华东    | 平板    | 2023-10-02 | 3000   | 3000     -- 华东平板:3000
6       | 华东    | 平板    | 2023-10-03 | 4000   | 7000     -- 华东平板:3000+4000

 关键语法: 

  1. PARTITION BY col1, col2:按多列组合进行分组,所有列相同的数据会被分到同一组。

  2. ORDER BY:指定组内的排序规则,决定累加的顺序。

      3.  窗口函数支持所有主流数据库(MySQL 8.0+、PostgreSQL、Kingbase、Orecle 等)

2. OVER() 窗口函数介绍

       SELECT  sale_id, region, product, sale_date,  amount, SUM(amount) OVER (
PARTITION BY region, product   ORDER BY sale_date  
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS cumulative_amount  FROM sales ORDER BY region, product, sale_date;

        在上面的 sql 中,OVER()窗口函数核心语法是定义一个数据窗口,可以理解为定义组内其它数据与当前行处理逻辑,例如上面 sql 的逻辑是,同一个分组内从第一行开始将数据累加到当前行。         注意:上面 sql 看似与 GROUP BY 处理相同,其实所有区别,窗口函数不会将多行数据合并为一行,而是在原有行的数据基础上为每行添加一个计算结果。

     2.1 基本使用语法
函数名(列名) OVER (窗口定义)

        1. 函数名:可以是聚合函数(SUMCOUNTAVG 等)或专用窗口函数(ROW_NUMBERRANKDENSE_RANK 等)。

        2. 窗口定义:通过 PARTITION BYORDER BY 等子句定义数据窗口对数据处理范围和规则。

    2.2  关键字说明

        1. PARTITION BY: 分组划分规则(可选),将数据按指定列分组,每个分组形成一个独立的空间,函数只在组内计算。

SELECT sale_date,region,amount,SUM(amount) OVER (PARTITION BY region ORDER BY sale_date) AS 区域累计销售额
FROM sales;

        2. ORDER BY:窗口内排序(可选),指定窗口内数据的排序规则

SELECT sale_date,amount,SUM(amount) OVER (ORDER BY sale_date) AS 全局累计销售额
FROM sales;

       3. 处理逻辑范围(可选),通过 ROWS 或 RANGE 精确指定窗口包含的行范围(默认是从组内第一行到当前行):

    3.1 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW :从组内第一行到当前行

    3.2 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING :从当前行到组内最后一行

    3.3 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ;当前行、前一行、后一行(共 3 行)

SELECT sale_date,amount,AVG(amount) OVER (ORDER BY sale_date ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS 近3行平均值
FROM sales;

3. 常见使用场景

  3.1  累计求和 / 平均值(聚合函数 +OVER()
SELECT id,amount,-- 累计求和SUM(amount) OVER (ORDER BY id) AS 累计金额,-- 移动平均值(前1行+当前行+后1行)AVG(amount) OVER (ORDER BY id ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS 移动平均
FROM sales;
3.2 组内排名(ROW_NUMBER/RANK/DENSE_RANK
SELECT region,amount,-- 组内按金额排名(不重复)ROW_NUMBER() OVER (PARTITION BY region ORDER BY amount DESC) AS 排名_不重复,-- 组内按金额排名(允许并列,跳过后续名次)RANK() OVER (PARTITION BY region ORDER BY amount DESC) AS 排名_跳号,-- 组内按金额排名(允许并列,不跳过后续名次)DENSE_RANK() OVER (PARTITION BY region ORDER BY amount DESC) AS 排名_连续
FROM sales;
3.3 组内首尾值 / 占比
SELECT region,amount,-- 组内最大金额MAX(amount) OVER (PARTITION BY region) AS 区域最高金额,-- 当前金额占组内总金额的比例amount / SUM(amount) OVER (PARTITION BY region) AS 区域占比
FROM sales;

与 GROUP BY 的区别

特性GROUP BYOVER() 窗口函数
结果行数每组返回一行保留原表所有行
计算范围整组数据可自定义窗口范围(如前 N 行)
适用场景统计各组汇总值需保留明细行的分析场景

总结

OVER() 函数的核心价值是:在不减少原表行数的前提下,实现对 "相关数据组" 的灵活计算,特别适合需要同时展示明细数据和聚合分析结果的场景(如报表中的累计占比、排名、移动平均等)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95674.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95674.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95674.shtml

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

相关文章

OpenRouter:一站式 AI 模型调用平台,免费畅享千问、DeepSeek 等顶级模型

欢迎来到我的博客,代码的世界里,每一行都是一个故事🎏:你只管努力,剩下的交给时间 🏠 :小破站 OpenRouter:一站式 AI 模型调用平台,免费畅享千问、DeepSeek 等顶级模型前…

SpringBoot 整合 Kafka 的实战指南

引言: 本文总字数:约 9800 字预计阅读时间:40 分钟 为什么 Kafka 是高吞吐场景的首选? 在当今的分布式系统中,消息队列已成为不可或缺的基础设施。面对不同的业务场景,选择合适的消息队列至关重要。目前…

OpenCV 实战篇——如何测算出任一副图片中的物体的实际尺寸?传感器尺寸与像元尺寸的关系?

文章目录1 如何测算出任一副图片中的物体的实际尺寸2 传感器尺寸与像元尺寸的关系3 Max Frame Rate最大帧率4 为什么要进行相机标定?相机标定有何意义?5 基于相机模型的单目测距--普通相机1 如何测算出任一副图片中的物体的实际尺寸 物体尺寸测量的思路是找一个确定尺寸的物…

Java并发锁相关

锁相关 ​1. 什么是可重入锁?Java 中如何实现?​​ ​答​: 可重入锁允许一个线程多次获取同一把锁(即递归调用时无需重新竞争锁)。 ​关键点​:防止死锁,避免线程因重复请求已持有的锁而阻塞。…

Pie Menu Editor V1.18.7.exe 怎么安装?详细安装教程(附安装包)​

​​Pie Menu Editor V1.18.7.exe​ 是一款用于创建和编辑 ​饼图菜单(Pie Menu)​​ 的工具软件,通常用于游戏开发、UI设计、3D建模(如 Blender 等)、或自定义软件操作界面。 一、准备工作 ​下载文件​ 下载了 ​Pi…

基于Spark的中文文本情感分析系统研究

引言 1.1 研究背景与意义 随着互联网的普及和社交媒体的兴起、特别是自媒体时代的来临,网络文本数据呈现爆炸式增长。这些文本数据蕴含着丰富的用户情感信息,如何有效地挖掘和利用这些信息,对于了解舆情动态、改进客户服务、辅助决策分析具…

Simulink子系统、变体子系统及封装知识

1.引言 文章三相新能源并网系统序阻抗模型——序阻抗分析器IMAnalyzer介绍了一种用于分析和扫描序阻抗的软件。其中,在序阻抗扫频操作过程中,用到了一个扰动注入、测量和运算工具【IMtool】,它外表长这样: 内部长这样&#xff1a…

高阶组件介绍

高阶组件约定俗成以with开头 import React, { useEffect } from react; import { TouchableOpacity, Image, StyleSheet } from react-native;type IReactComponent React.ClassicComponentClass| React.ComponentClass| React.FunctionComponent| React.ForwardRefExoticComp…

C++ STL系列-02.泛型入门

C STL系列-02.泛型入门C中的泛型编程主要通过模板(template)实现。模板允许我们编写与类型无关的代码,是一种将类型作为参数进行编程的方式。在C中,模板分为函数模板和类模板。 1. 函数模板函数模板允许我们定义一个函数&#xff…

高效管理网络段和端口集合的工具之ipset

目录 1. 核心命令速查 2. 集合类型 3. 实战案例:使用 ipset 封禁 IP 案例 1:基础黑名单封禁(手动添加) 案例 2:自动过期和解封 案例 3:封禁 IP 和端口组合 案例 4:白名单模式 案例 5&am…

实例和对象的区别

对象(Object)是一个概念,它表示“某个类的一个成员”,是“逻辑上的个体”。实例(Instance)是一个现实,指的是在内存中真正分配了空间的对象。实例一定是对象,但对象不一定是实例。例…

Win10 Chrome认不出新Emoji?两个扩展搞定显示与输入

前言 用Win10电脑在Chrome里发消息、刷网页时,你是否遇到过这样的尴尬:别人发的、或者页面显示的 Emoji,在你屏幕上变成了空白方框,像“文字里缺了一块拼图”?其实这不是Chrome的错,也不用换电脑&#xff0…

Golang中逃逸现象, 变量“何时栈?何时堆?”

目录 什么是栈 什么是堆 栈 vs 堆(核心区别) GO编译器的逃逸分析 什么是逃逸分析? 怎么看逃逸分析结果? 典型“会逃逸”的场景 闭包捕获局部变量 返回或保存带有“底层存储”的容器 经由接口/反射/fmt 等导致装箱或被长…

MySQL入门指南:从安装到工作原理

什么是MySQL MySQL是一个开源的关系型数据库管理系统,由瑞典MySQL AB公司开发(目前属于Oracle公司),被广泛地应用在大中小型网站中 MySQL是一个小型的开源的关系型数据库管理系统,与其他大型数据库管理系统例如&…

dask.dataframe.shuffle.set_index中获取 divisions 的步骤分析

dask.dataframe.shuffle.set_index 中获取 divisions 的步骤分析 主要流程概述 在 set_index 函数中,当 divisionsNone 时,系统需要通过分析数据来动态计算分区边界。这个过程分为以下几个关键步骤: 1. 初始检查和准备 if divisions is None:…

ai生成ppt工具有哪些?10款主流AI生成PPT工具盘点

随着人工智能技术的飞速发展,AI生成PPT工具逐渐成为职场人士、学生和创作者提升效率的得力助手。这类工具通过智能算法,能够快速将文本、数据或创意转化为结构化、视觉化的演示文稿,大幅节省设计时间。1、AiPPT星级评分:★★★★★…

Qt多线程编程学习

Qt多线程编程学习 1. 项目概述 本项目展示了Qt中多线程编程的基本用法,通过继承QThread类创建自定义线程,并演示了线程的启动、执行和销毁过程。项目包含一个简单的用户界面,用户可以通过按钮控制线程的启动和结束。 1.1 项目结构 项目包含以…

加密货币武器化:恶意npm包利用以太坊智能合约实现隐蔽通信

ReversingLabs研究人员发现两个恶意npm包利用以太坊(Ethereum)智能合约隐藏并传播恶意软件。这两个名为colortoolsv2和mimelib2的软件包于2025年7月被识别,展现了开源安全攻防战中的新战术。恶意软件包伪装成实用工具攻击活动始于7月7日发布的…

Spring Boot 全局字段处理最佳实践

在日常开发中,我们总会遇到一些琐碎但又无处不在的字段处理需求:• 请求处理: 用户提交的表单,字符串前后带了多余的空格,需要手动 trim()。• 响应处理: 返回给前端的 BigDecimal 金额,因为精度问题导致JS处理出错&am…

三坐标测量机在汽车制造行业中的应用

在汽车制造业中,零部件精度决定着整车性能。从发动机活塞的微米级公差,到车身焊接的毫米级间隙,汽车制造“差之毫厘,谬以千里” ,任何细微偏差都可能引发连锁反应:发动机抖动、异响、油耗飙升,车…