SQL窗口函数OVER与GROUP BY区别_分析查询性能与适用场景

张开发
2026/4/18 0:04:03 15 分钟阅读

分享文章

SQL窗口函数OVER与GROUP BY区别_分析查询性能与适用场景
OVER不能替代GROUP BY因二者作用层级不同GROUP BY聚合归并行集输出行数≤输入OVER保留原始行结构叠加计算输出行数输入需压缩行数用GROUP BY需每行附加统计值才用OVER。OVER 不能替代 GROUP BY因为它们作用层级不同GROUP BY 是对行集做聚合归并输出结果行数 ≤ 输入行数OVER 是在保留原始行结构基础上叠加计算输出行数 输入行数。如果你需要把 100 行压缩成 10 行统计结果GROUP BY 是唯一正解如果要在每行上显示“当前用户订单总额”或“部门平均薪资”才轮到 OVER 出场。常见错误现象SELECT user_id, SUM(amount) OVER(PARTITION BY user_id), COUNT(*) FROM orders —— 这里 COUNT(*) 没加窗口定义会报错或返回全表计数不是每个用户的订单数。聚合函数在 OVER 中必须显式声明窗口PARTITION BY / ORDER BY否则默认是整个结果集GROUP BY 后所有非聚合字段必须出现在 GROUP BY 列表中而 OVER 可以和任意字段共存不破坏原始行粒度混合使用时注意逻辑顺序SQL 执行顺序是 FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BYOVER 在 SELECT 阶段计算所以看不到 WHERE 之后被过滤掉的行但能看到 GROUP BY 后的聚合结果只要没用 GROUP BY 掩盖原始行性能差异GROUP BY 通常更重OVER 可能触发重复扫描GROUP BY 一般需要哈希构建或排序中间结果不可复用OVER 看似轻量但多个不同 PARTITION BY 或 ORDER BY 的窗口函数可能让优化器为同一数据集执行多次分组/排序——尤其是 PostgreSQL 和 SQL Server 中较明显。使用场景提示查“每个销售员当月销售额 全公司销售额占比 同岗位平均值”三个指标分别依赖不同分区PARTITION BY sales_id、PARTITION BY 1、PARTITION BY role此时引擎大概率会扫描三次基础数据。MySQL 8.0 对单表多窗口有合并优化但跨表 JOIN 后的窗口仍易退化避免在 OVER(ORDER BY ... ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 中对高基数列排序会导致大量临时排序开销如果只需要全局统计如总金额、最大值直接用 SUM(amount) OVER() 比 (SELECT SUM(amount) FROM t) 子查询更高效且无需关联NULL 值和排序行为PARTITION BY 和 ORDER BY 对 NULL 的处理不一致PARTITION BY col 默认把 NULL 当作一个独立分区而 ORDER BY col 在窗口中默认把 NULL 排在最前PostgreSQL或最后MySQL且无法用 NULLS FIRST/LAST 统一控制MySQL 不支持该语法。 JoinMC智能客服 JoinMC智能客服帮您熬夜加班7X24小时全天候智能回复用户消息自动维护媒体主页全平台渠道集成管理电商物流平台一键绑定让您出海轻松无忧

更多文章