Answers:
它们在不同的地方使用。 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
可以在SELECT语句中使用SQL GROUP BY子句来收集多个记录中的数据,并将结果按一个或多个列分组。
简而言之,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
在转到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
会影响行数,只会减少行数。
SELECT
成 SELECT DISTINCT
以第二查询?那会不会返回与GROUP BY
查询相同的数据集?选择其中一个的原因是什么?
partition by
实际上不会汇总数据。它使您可以按组重置某些内容。例如,通过在分组字段上分区并使用rownum()
该组中的行,可以在组中获得序数列。这使您的行为有点像在每个组的开头重置的标识列。
它提供汇总数据而无需汇总
即假设我想返回销售区域的相对位置
使用PARTITION BY,我可以返回给定区域的销售金额以及同一行中所有销售区域的最大金额。
这确实意味着您将拥有重复的数据,但是就数据已聚合但没有数据丢失的意义而言,它可能适合最终用户(与GROUP BY一样)。
据我了解,Partition By与Group By几乎相同,但有以下差异:
该group by实际上将结果集分组,每组返回一行,因此导致SQL Server仅允许SELECT列表中的聚合函数或列为group by子句的列(在这种情况下,SQL Server可以保证唯一每组的结果)。
例如,考虑允许在SELECT列表中使用Group By子句中未定义的列的MySQL,在这种情况下,每个组仍返回一行,但是,如果该列没有唯一结果,则无法保证输出是什么!
但是使用Partition By,虽然该函数的结果与使用Group By的聚合函数的结果相同,但您仍将获得正常的结果集,这意味着每个基础行仅获得一行,而不是每个基础行获得一行组,因此在SELECT列表中每个组的列可能不是唯一的。
因此,作为总结,Group By在每个组需要输出一行时是最好的,而Partition By在需要所有行但仍希望基于组的聚合函数时最好。
当然也可能存在性能问题,请参阅http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba。
使用时 GROUP BY
,结果行通常少于传入行。
但是,当您使用时PARTITION BY
,结果行数应与传入的行数相同。
假设我们有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行
它的使用情况确实不同。当您使用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