SQL Server : PARTITION BY와 GROUP BY의 차이점


365

내가 사용했던 GROUP BY지난 몇 년 동안 집계 쿼리의 모든 종류. 최근에는 PARTITION BY집계를 수행 하는 데 사용 되는 일부 코드를 리버스 엔지니어링했습니다 . 내가 찾을 수있는 모든 문서를 읽을 때 약간의 추가 기능이 추가 된 PARTITION BY것처럼 들리 GROUP BY나요? 그것들은 동일한 일반 기능의 두 가지 버전입니까, 아니면 완전히 다른 것입니까?

답변:


440

그들은 다른 장소에서 사용됩니다. 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

A는 group by일반적으로 그들을 롤링 각 행에 대한 평균 또는 합을 계산하여 반환 된 행의 수를 감소시킨다. partition by반환 된 행 수에는 영향을 미치지 않지만 창 함수의 결과 계산 방법이 변경됩니다.


23
좋은 대답, 당신은 그들 각각에 대해 반환 결과의 샘플을 작성 하시겠습니까?
Ashkan Mobayen Khiabani

2
@AshkanMobayenKhiabani Northwind에 대해 두 쿼리를 모두 실행할 수 있으며 SQL 서버 버전에 따라 기본적으로 설치되거나 설치되지 않을 수 있습니다. 그렇지 않은 경우 다운로드 페이지에서 검색 할 수 있습니다.
Fetchez la vache

15
점프에 반대 쇼 아래 @AshkanMobayenKhiabani Arunprasanth의 대답은 Northwind를 배우고 더 학습 농구와 시간을 통해 시간을 절약 할 수 있습니다 결과를 반환
프락시 텔레스

1
Windows 기능에 대한 추가 정보 (SQL) : blog.jooq.org/2013/11/03/…
datps

itcodehub.blogspot.com/2019/03/…-SQL 에서 그룹 별 및 파티션 별 차이점에 대한 자세한 정보 및 예
xproph

252

간단한 예를 들어 보겠습니다.

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와 달리 행을 분할하고 모든 행을 반환 합니다 .


3
partition by 수에 영향을 줄 수 있지만 행 수를 줄이지 않습니다 .
John

1
를 두 번째 쿼리 SELECT로 변경하면 차이점은 무엇입니까 SELECT DISTINCT? GROUP BY쿼리 와 동일한 데이터 세트를 반환하지 않습니까? 하나 또는 다른 것을 선택하는 이유는 무엇입니까?
Erick 3E

3
@ Erick3E이 질문을 살펴 보시기 바랍니다 stackoverflow.com/questions/20375074/…
Arunprasanth KV

이 답변은 파티션에서 집계 함수 Min / Max / Sum 등이 작동하는 방식을 보여주기 때문에 더 좋습니다. Row_Number () 예제는 명확하지 않습니다. 일반적으로 GROUP BY와 함께 집계 함수를 사용하지만 PARTITION-OVER가 동일한 방법을 사용하고 OP가 한 것과 동일한 것을 궁금해했습니다. 감사!
ripvlan

53

partition by실제로 데이터를 롤업하지 않습니다. 그룹별로 무언가를 재설정 할 수 있습니다. 예를 들어 그룹화 필드를 분할하고 해당 그룹 rownum()내의 행을 사용하여 그룹 내 서수 열을 가져올 수 있습니다 . 이를 통해 각 그룹의 시작 부분에서 재설정되는 ID 열과 같은 방식으로 작동합니다.


43

PARTITION BY 결과 집합을 파티션으로 나눕니다. 윈도우 기능은 각 파티션에 개별적으로 적용되며 각 파티션마다 계산이 다시 시작됩니다.

이 링크에서 발견 : OVER Clause


36

롤업하지 않고 롤업 된 데이터를 제공합니다

즉, 판매 지역의 상대 위치를 반환한다고 가정합니다.

PARTITION BY를 사용하면 특정 지역의 판매액 모든 판매 지역의 MAX 금액을 같은 행에 반환 할 수 있습니다 .

이는 데이터가 반복된다는 것을 의미하지만 GROUP BY와 마찬가지로 데이터가 집계되었지만 데이터가 손실되지 않았다는 점에서 최종 소비자에게 적합 할 수 있습니다.


3
가장 간단한 답변입니다.
tmthyjames

27

PARTITION BY분석하는 동안 GROUP BY집계됩니다. 사용 PARTITION BY하려면 OVER 절 과 함께 포함시켜야합니다 .


1
PARTITION BY is analytic이 간단한 진술은 저에게 많은 도움이되었습니다. +1.

이것은 실제로 가장 단순하고 최상의 답변입니다.
jdmneon

22

내가 이해 한대로 Partition By는 Group By와 거의 동일하지만 다음과 같은 차이점이 있습니다.

이 그룹은 실제로 그룹당 하나의 행을 반환하는 결과 집합을 그룹화하므로 SQL Server는 SELECT by list by group by 절의 일부인 함수 또는 열만 허용합니다 (이 경우 SQL Server는 고유함을 보장 할 수 있음) 각 그룹에 대한 결과).

예를 들어 Group By 절에 정의되지 않은 SELECT 목록 열을 가질 수있는 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 참조) .


2

을 사용 GROUP BY하면 결과 행은 일반적으로 들어오는 행보다 적습니다.

그러나를 사용할 때 PARTITION BY결과 행 수는 수신과 동일해야합니다.


0

name테이블에 14 개의 열 레코드가 있다고 가정 하십시오.

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 행 증가합니다


0

작은 관찰. '파티션 기준'을 사용하여 SQL을 동적으로 생성하는 자동화 메커니즘 '그룹 별'과 관련하여 구현하는 것이 훨씬 간단합니다. 'group by'의 경우 'select'열의 내용을 처리해야합니다.

내 영어가 유감입니다.


0

사용 시나리오가 실제로 다릅니다. GROUP BY를 사용하면 동일한 열에 대한 일부 레코드가 병합되고 결과 집합이 집계됩니다.

그러나 PARTITION BY를 사용하면 결과 집합은 동일하지만 창 기능에 대한 집계 만 있고 레코드를 병합하지 않아도 여전히 동일한 레코드 수를 갖게됩니다.

다음은 차이점을 설명하는 유용한 집필입니다. http://alevryustemov.com/sql/sql-partition-by/


-1
-- 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.