多年来,我一直在对所有类型的聚合查询使用GROUP BY。最近,我一直在逆向工程一些使用PARTITION BY来执行聚合的代码。

在阅读我能找到的所有关于PARTITION BY的文档时,它听起来很像GROUP BY,可能还添加了一些额外的功能。

它们是相同功能的两个版本还是完全不同的东西?


当前回答

它有非常不同的使用场景。 当您使用GROUP BY时,您合并了相同列的一些记录,并获得了结果集的聚合。

然而,当你使用PARTITION BY时,你的结果集是相同的,但你只是对窗口函数进行了聚合,而你没有合并记录,你仍然会有相同的记录计数。

以下是一篇对市场有帮助的文章,解释了两者的区别: http://alevryustemov.com/sql/sql-partition-by/

其他回答

分区并不会实际卷起数据。它允许您在每个组的基础上重置一些东西。例如,通过对分组字段进行分区并对组中的行使用rownum(),可以获得组中的序数列。这使您的行为有点像在每个组的开头重置的标识列。

它有非常不同的使用场景。 当您使用GROUP BY时,您合并了相同列的一些记录,并获得了结果集的聚合。

然而,当你使用PARTITION BY时,你的结果集是相同的,但你只是对窗口函数进行了聚合,而你没有合并记录,你仍然会有相同的记录计数。

以下是一篇对市场有帮助的文章,解释了两者的区别: http://alevryustemov.com/sql/sql-partition-by/

它们被用在不同的地方。GROUP BY修改整个查询,比如:

select customerId, count(*) as orderCount
from Orders
group by customerId

但是PARTITION BY只适用于窗口函数,比如ROW_NUMBER():

select row_number() over (partition by customerId order by orderId)
    as OrderNumberForThisCustomer
from Orders

GROUP BY通常减少滚动返回的行数 他们计算每行的平均值或总和。 PARTITION BY不影响返回的行数,但是它 更改窗口函数结果的计算方式。

假设我们在表中有14条name列的记录

在小组由

select name,count(*) as totalcount from person where name='Please fill out' group BY name;

它将给出单行计数,即14

但是在除以

select row_number() over (partition by name) as total from person where name = 'Please fill out';

它将增加14行计数

它提供汇总数据而不进行汇总

例如,假设我想返回销售区域的相对位置

使用PARTITION BY,我可以返回给定区域的销售额和同一行中所有销售区域的最大销售额。

这确实意味着您将有重复的数据,但它可能适合最终消费者,因为数据已经聚合,但没有数据丢失——就像GROUP BY的情况一样。