我一直在使用 GROUP BY 适用于多年来所有类型的聚合查询。最近,我一直在对一些使用的代码进行逆向工程 PARTITION BY 执行聚合。在阅读所有文档时,我可以找到有关 PARTITION BY, ,听起来很像 GROUP 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不影响返回的行的数目,但它变化的窗口函数的结果的计算方式。

其他提示

我们可以采取一个简单的例子。

考虑的表名为TableA具有以下值:

id  firstname                   lastname                    Mark
-------------------------------------------------------------------
1   arun                        prasanth                    40
2   ann                         antony                      45
3   sruthy                      abc                         41
6   new                         abc                         47
1   arun                        prasanth                    45
1   arun                        prasanth                    49
2   ann                         antony                      49

<强> GROUP BY

  

在SQL GROUP BY子句可以在SELECT语句中被使用,以收集   由一个或多个跨多个记录和组的结果数据   列。

     

在更简单的话GROUP BY语句结合使用具有   的合计函数组的结果集由一个或多个   列。

语法:

SELECT expression1, expression2, ... expression_n, 
       aggregate_function (aggregate_expression)
FROM tables
WHERE conditions
GROUP BY expression1, expression2, ... expression_n;

我们可以在我们的表应用GROUP BY

select SUM(Mark)marksum,firstname from TableA
group by id,firstName

结果:

marksum  firstname
----------------
94      ann                      
134     arun                     
47      new                      
41      sruthy   

在我们的真正的表,我们有7行,当我们申请GROUP BY id,基于id服务器组的结果:

在简单的话:

  

这里GROUP BY通常会降低滚动返回的行数   起来,并为每一行计算Sum()

<强> PARTITION BY

在去按分区,让我们来看看OVER条款:

<强>按照MSDN定义:

  

OVER子句定义内的一个窗口或用户组指定的行   查询结果集。窗函数,然后计算一个值的每一行   在窗口中。您可以使用OVER子句的功能来计算   聚合值如移动平均,累积的聚集体,   运行总和,或每个组的结果的前N个

PARTITION BY不会减少的行数返回。

我们可以在我们的例子表应用PARTITION BY:

SELECT SUM(Mark) OVER (PARTITION BY id) AS marksum, firstname FROM TableA

结果:

marksum firstname 
-------------------
134     arun                     
134     arun                     
134     arun                     
94      ann                      
94      ann                      
41      sruthy                   
47      new  

看结果 - 它将把行和回报的所有的行,不像GROUP BY

partition by实际上不卷起的数据。它可以让你重置以组为单位的东西。例如,您可以通过分割的分组字段,并使用rownum()在该组中的行得到了组内的序号列。这给你的东西,行为有点像一个重置在每个组的开始标识列。

  

PARTITION BY   划分结果集到分区。窗口函数应用于单独每个分区和计算重新启动用于每个分区。

在此链接。实测值: OVER第

它提供了汇总的数据而不滚了

即假如我想要返回的相对位置的销售区

采用分区,我可以返回的销售量为某一区域 最大数额所有销售的地区,在同一行。

这并不意味着你将有重复的数据,但它可以满足终端消费者的意义上说,数据已经汇总,但没有数据已经失去了-为的情况与组。

PARTITION BY解析,而GROUP BY是聚集体。为了使用PARTITION BY,你有一个 OVER子句来遏制它

据我了解,Partition By 与 Group By 几乎相同,但有以下区别:

该 group by 实际上对每组返回一行的结果集进行分组,这会导致 SQL Server 只允许在 SELECT 列表中使用属于 group by 子句的聚合函数或列(在这种情况下,SQL Server 可以保证有唯一的每组的结果)。

例如,MySQL 允许在 SELECT 列表中包含未在 Group By 子句中定义的列,在这种情况下,每组仍返回一行,但是如果该列没有唯一的结果,则无法保证输出是什么!

但是使用 Partition By 时,虽然该函数的结果与使用 Group By 的聚合函数的结果相同,但您仍然得到正常的结果集,这意味着每个底层行获取一行,而不是每个行获取一行。组,因此,在 SELECT 列表中,每个组可以具有不唯一的列。

总而言之,当需要每组输出一行时,Group By 是最好的,而当需要所有行但仍需要基于组的聚合函数时,Partition By 是最好的。

当然也可能存在性能问题,参见 http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba.

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

group by

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

它会给计数在单列即14

但在partition by

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

它将在计数

的增加的14行

小观察。自动化机制来动态地生成使用SQL“分区的”这是很简单的关于落实到“GROUP BY”。在“按组”的情况下,我们必须采取“选择”列的内容的服务。

对不起,我的英语。

它确实不同的使用场景。 当您使用GROUP BY您合并一些记录是相同的列和你有结果集的集合。

然而,当您使用PARTITION BY结果集是相同的,但你只要在窗口功能的聚集和你不合并的记录,你仍然有记录相同的数量。

下面是一个反弹有用的文章,解释的区别: http://alevryustemov.com/sql/sql-partition-by/

-- BELOW IS A SAMPLE WHICH OUTLINES THE SIMPLE DIFFERENCES
-- READ IT AND THEN EXECUTE IT
-- THERE ARE THREE ROWS OF EACH COLOR INSERTED INTO THE TABLE
-- CREATE A database called testDB


-- use testDB
USE [TestDB]
GO


-- create Paints table
CREATE TABLE [dbo].[Paints](
    [Color] [varchar](50) NULL,
    [glossLevel] [varchar](50) NULL
) ON [PRIMARY]

GO


-- Populate Table
insert into paints (color, glossLevel)
select 'red', 'eggshell'
union
select 'red', 'glossy'
union
select 'red', 'flat'
union
select 'blue', 'eggshell'
union
select 'blue', 'glossy'
union
select 'blue', 'flat'
union
select 'orange', 'glossy'
union
select 'orange', 'flat'
union
select 'orange', 'eggshell'
union
select 'green', 'eggshell'
union
select 'green', 'glossy'
union
select 'green', 'flat'
union
select 'black', 'eggshell'
union
select 'black', 'glossy'
union
select 'black', 'flat'
union
select 'purple', 'eggshell'
union
select 'purple', 'glossy'
union
select 'purple', 'flat'
union
select 'salmon', 'eggshell'
union
select 'salmon', 'glossy'
union
select 'salmon', 'flat'


/*   COMPARE 'GROUP BY' color to 'OVER (PARTITION BY Color)'  */

-- GROUP BY Color 
-- row quantity defined by group by
-- aggregate (count(*)) defined by group by
select count(*) from paints
group by color

-- OVER (PARTITION BY... Color 
-- row quantity defined by main query
-- aggregate defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color)
from paints

/* COMPARE 'GROUP BY' color, glossLevel to 'OVER (PARTITION BY Color, GlossLevel)'  */

-- GROUP BY Color, GlossLevel
-- row quantity defined by GROUP BY
-- aggregate (count(*)) defined by GROUP BY
select count(*) from paints
group by color, glossLevel



-- Partition by Color, GlossLevel
-- row quantity defined by main query
-- aggregate (count(*)) defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color, glossLevel)
from paints
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top