SQL中PARTITION BY和GROUP BY有什么区别

来源:前端技术作者:天马头衔:网络博主
导读:本期聚焦于小伙伴创作的《SQL中PARTITION BY和GROUP BY有什么区别》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL中PARTITION BY和GROUP BY有什么区别》有用,将其分享出去将是对创作者最好的鼓励。

在SQL查询中,PARTITION BY和GROUP BY都是用于分组的关键字,但两者的运行逻辑和适用场景有本质区别,很多开发者在初学窗口函数时容易混淆这两个概念,导致查询结果不符合预期。

GROUP BY的核心逻辑

GROUP BY是标准SQL聚合查询的关键字,它的作用是将表中具有相同分组字段值的行合并成一行,最终返回的结果行数等于分组的数量。使用GROUP BY时,查询的SELECT子句只能包含分组字段和聚合函数(如SUM、COUNT、AVG等),不能直接返回原表的明细字段。

比如我们有一张订单表order_info,包含字段order_id(订单ID)、user_id(用户ID)、order_amount(订单金额),现在要统计每个用户的订单总金额,使用GROUP BY的查询如下:

-- 统计每个用户的订单总金额
SELECT 
    user_id,
    SUM(order_amount) AS total_amount,
    COUNT(order_id) AS order_count
FROM order_info
GROUP BY user_id;

上述查询执行后,每个user_id只会对应一行结果,原表中同一个用户的多条订单记录会被合并,无法直接看到单条订单的明细信息。

PARTITION BY的核心逻辑

PARTITION BY是窗口函数的配套关键字,它不会改变原查询结果的行数,只是为每一行数据划分一个独立的计算窗口,窗口函数会在这个窗口内完成计算,最终每一行都会保留自己的原始明细,同时附带窗口函数的计算结果。

同样用上面的订单表举例,如果我们要在保留每一条订单明细的同时,加上该订单所属用户的订单总金额,就可以用PARTITION BY配合SUM窗口函数实现:

-- 保留订单明细,同时统计每个用户的订单总金额
SELECT 
    order_id,
    user_id,
    order_amount,
    SUM(order_amount) OVER (PARTITION BY user_id) AS user_total_amount
FROM order_info;

上述查询执行后,结果行数和原订单表的行数完全一致,每一行都包含完整的订单明细,同时user_total_amount字段会显示对应用户的订单总金额。

两者的核心差异对比

为了更清晰地区分两者的差异,我们可以从以下几个维度对比:

对比维度GROUP BYPARTITION BY
结果行数合并分组,行数等于分组数不改变行数,和原查询行数一致
返回内容只能返回分组字段和聚合结果可以保留原表所有明细字段,同时返回窗口计算结果
使用场景需要分组聚合统计,不需要明细的场景需要保留明细,同时做分组统计的场景
配套函数配合SUM、COUNT等普通聚合函数使用配合ROW_NUMBER、RANK、SUM等窗口函数使用

窗口函数的运行原理

窗口函数的执行逻辑可以分为三步:

  • 第一步:执行FROM和WHERE子句,筛选出符合条件的基础数据行
  • 第二步:根据PARTITION BY指定的字段对数据行进行分区,相同字段值的行会被划分到同一个窗口
  • 第三步:在每个窗口内,按照ORDER BY指定的排序规则对行排序,再执行窗口函数计算,将结果附加到每一行上

需要注意的是,窗口函数只能出现在SELECT子句中,不能用于WHERE、GROUP BY等子句,因为窗口函数的执行顺序在这些子句之后。

常见使用误区

很多开发者会误以为PARTITION BY和GROUP BY可以互相替换,实际上两者的适用场景完全不同。如果需要的是分组后的聚合汇总结果,不需要明细,就用GROUP BY;如果需要在保留所有明细的同时,给每一行加上分组统计的结果,就用PARTITION BY配合窗口函数。如果错误地在需要明细的场景用了GROUP BY,就会丢失原始数据;如果在只需要聚合结果的场景用了PARTITION BY,会导致结果冗余,增加后续处理成本。

另外,PARTITION BY可以省略,如果省略的话,整个查询结果会被当作一个大的窗口,窗口函数会基于所有行进行计算,比如要计算所有订单的总金额,同时保留每一条订单明细,就可以这样写:

-- 保留订单明细,同时统计所有订单的总金额
SELECT 
    order_id,
    user_id,
    order_amount,
    SUM(order_amount) OVER () AS all_total_amount
FROM order_info;

SQLPARTITION_BYGROUP_BY窗口函数修改时间:2026-06-08 21:21:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。