SQL服务器:PARTITION BY 和 GROUP BY 的区别
-
18-09-2019 - |
题
我一直在使用 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