You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LISTAGG处理VARCHAR数据时,Partition与Group By哪种更高效?

关于LISTAGG两种写法的效率对比及场景分析

首先得明确:这两种写法本质返回的结果完全不同,这是分析效率的核心前提:

  • 写法一(GROUP BY聚合):按department_id分组,每个部门仅返回一行结果,对应该部门的员工列表
  • 写法二(窗口函数):返回每一条员工记录,且每条记录都附带其所在部门的员工列表,结果行数等于员工总数

效率对比

如果你的需求是获取每个部门一行的聚合结果,写法一的效率会显著更高:

  1. 计算量:写法一仅对每个部门做一次LISTAGG聚合;写法二需要为每一条员工记录重复计算所在部门的员工列表,冗余计算量极大
  2. 数据传输:写法一返回行数是部门数量,写法二是员工总数,后者的数据量要大得多,对网络、存储的消耗也更明显

如果你的需求是保留每条员工的原始数据,同时附带所在部门的员工列表,那写法二是唯一适配的选择,这时就不用纠结效率——需求本身决定了必须用窗口函数实现。

关于你的使用习惯

你提到“除非仅选择1-2列,否则总会用Partition,因为无需将每个列都加入GROUP BY子句”,这个习惯要结合需求场景调整:

  • 如果最终需要的是聚合后的分组结果,哪怕要选多列,也应该用GROUP BY(把需要展示的非聚合列加入GROUP BY,或用聚合函数处理),避免用窗口函数后再去重,那样反而会额外增加开销
  • 如果需要每条原始记录都附带聚合信息,窗口函数确实更便捷,不用额外处理分组逻辑

两种写法的代码示例

写法一(GROUP BY聚合):

SELECT department_id AS "Dept.", 
       LISTAGG(last_name, '; ') WITHIN GROUP (ORDER BY hire_date) AS "Employees" 
FROM employees 
GROUP BY department_id 
ORDER BY department_id;

写法二(窗口函数):

SELECT department_id AS "Dept.", 
       LISTAGG(last_name, '; ') WITHIN GROUP (ORDER BY hire_date) OVER (PARTITION BY department_id) AS "Employees" 
FROM employees 
ORDER BY department_id;

内容的提问来源于stack exchange,提问作者AJQShake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:52:53