由 John Doe 四月 8, 2023
摘要:GROUP BY
和PARTITION BY
子句在 SQL 中都用于对数据进行分组和计算聚合值,那么它们之间有什么区别呢?
目录
介绍
GROUP BY 和 PARTITION BY 子句在 SQL 中用于对数据进行分组和计算聚合值。GROUP BY
子句将结果集划分为多个组,每个组返回一行,而PARTITION BY
子句将结果集划分为多个组,返回每个组中的每条记录,并带上每个组的聚合列。GROUP BY
子句通常与SUM()
和AVG()
等聚合函数一起使用,以计算每个组的总和或平均值。PARTITION BY
子句不会减少返回的行数。PARTITION BY
子句在选择分组列时提供了更大的灵活性,并允许在每个分组中使用不同的列。
GROUP BY 的使用
下面是一个例子用于展示如何将每个部门员工的平均薪水进行比较:
SELECT depname, avg(salary) FROM empsalary GROUP BY depname;
depname | avg
-----------+-----------------------
develop | 5020.0000000000000000
personnel | 3700.0000000000000000
sales | 4866.6666666666666667
(3 rows)
最开始的一个输出列直接来自于表empsalary
,并且该列只能指定为进行分组的列。第二列表示根据depname
值进行分组统计取得的平均薪水值。
PARTITION BY 的使用
下面是一个例子用于展示如何将每一个员工的薪水与他/她所在部门的平均薪水进行比较:
SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
depname | empno | salary | avg
-----------+-------+--------+-----------------------
develop | 11 | 5200 | 5020.0000000000000000
develop | 7 | 4200 | 5020.0000000000000000
develop | 9 | 4500 | 5020.0000000000000000
develop | 8 | 6000 | 5020.0000000000000000
develop | 10 | 5200 | 5020.0000000000000000
personnel | 5 | 3500 | 3700.0000000000000000
personnel | 2 | 3900 | 3700.0000000000000000
sales | 3 | 4800 | 4866.6666666666666667
sales | 1 | 5000 | 4866.6666666666666667
sales | 4 | 4800 | 4866.6666666666666667
(10 rows)
最开始的三个输出列直接来自于表empsalary
,并且表中每一行都有一个输出行。第四列表示对与当前行具有相同depname
值的所有表行取得平均值(这实际和非窗口avg
聚集函数是相同的函数,但是OVER
子句使得它被当做一个窗口函数处理并在一个合适的窗口帧上计算。)。
总结
虽然我们大多数时候使用GROUP BY
,但在很多情况下,PARTITION BY
会是更好的选择。在某些情况下,您可以使用子查询的GROUP BY
来模拟PARTITION BY
,但这些查询最终可能会非常复杂。
让我们用最重要的相似点和差异点来总结一切:
- 相似点:两者都用于返回聚合值。
- 差异点:使用
GROUP BY
子句隐藏了原始行,您无法在查询中访问原始行的记录值。另一方面,使用PARTITION BY
子句可以保留原始列值,同时也允许我们生成聚合列值。 - 差异点:
PARTITION BY
与OVER()
和窗口函数相结合,可以支持更多功能。