관리 메뉴

JIE0025

[MySQL] GROUP BY, PARTITION BY 차이점 본문

백엔드/데이터베이스

[MySQL] GROUP BY, PARTITION BY 차이점

Kangjieun11 2022. 12. 5. 02:35
728x90

 

 

 GROUP BY와 PARTITION BY의 가장 큰 차이점은 행 수이다.

 

 

 

✅  GROUP BY

GROUP BY 절은 특정 칼럼을 기준으로 집계 함수를 사용하여 건수(COUNT), 합계(SUM), 평균(AVG) 등 집 계성 데이터를 추출할 때 사용

 

 

  • group 에 따라 행을 집약해 결과를 도출함
  • 하나 이상의 컬럼을 기준으로 컬럼값에 따라 그룹화 하여 그룹별로 출력한다.

 

집계 함수를 사용하여 기존 행에 있던 값들을 계산한 후 새로운 행에 입력해 주는데,

집계 함수가 데이터를 하나로 합쳐주는 과정에서, 기존의 상세 데이터들을 잃게 된다.

 

 

✔️ group by 유의사항 함께보기

  •  그룹함수 사용시 단순 컬럼은 SELECT 리스트에 올 수 없다. 
  •  단 GROUP BY 절 뒤에 묶인 단순 컬럼은 SELECT 리스트에 기술할 수 있다.  

쿼리의 작동순서는  from - where - group by - having - select - orderby 이므로,
group by 뒤에 오는 select / order by에서 개별데이터를 사용하게 되면 에러가 발생한다.

왜냐? 그룹화를 하면서 이미 세부데이터가 사라졌기 때문이다.! 

  • 기존의 상세 데이터가 사라지는걸 기억하면 기억하기 쉬운 유의사항이 될것이다.

 

✅  PARTITION BY

 

GROUP BY와 집계 함수가 하는 역할과 거의 유사하지만, 차이점이 1가지 존재함.

PARTITION BY를 사용하면, GROUP BY와는 달리 기존 행의 세세한 정보들은 사라지지 않고 그대로 유지된다.

 

기존의 데이터와 집계된 값을 함께 나란히 볼 수 있다는 이야기! 

  • 행을 집약한 결과를 보여주지는 않는다.
  • 레코드가 줄어들지 않는다.

 

 

 

 

 

✔️  쉬운 이해를 돕기 위한 예제

 

ID가 'k'로 시작하는 회원들의 구매한 제품들 가격의 총합을 출력해주고 싶다. 

 

▪️ 테스트 데이터 (기대값)

 KHD id를 가진 회원이 구매한 물건 리스트를 출력했다. 



KHD는 10원짜리 어댑터 1개, 15원짜리 양말 10개, 5원짜리 콜라 10개를 구매했다.

10+ 150 + 50 = 210을 기대값으로 가진다. 

 

 

GROUP BY와 PARTITION BY를 써서 데이터를 추출해보자.

PARTITION BY를 썼냐, GROUP BY를 썼냐만 차이를 줬는데 약간 쿼리가 달라졌다. 

-- GROUP BY
-- O.name as '제품이름', O.price '제품가격',O.count as '구매개수', 사용불가  : 행이 집약되어서 세부 데이터를 볼 수 없음 

select Distinct U.id, U.name as '구매한 사람', 
SUM(O.price * O.count) as '가격총합'
from userTbl U
inner join orderTbl O
on O.userid = U.id
where O.userid LIke 'k%'
group by U.id
order by U.name;




-- PARTITION BY 
-- 행이 집약되지 않기 때문에 세부 데이터를 볼 수 있음.

select Distinct U.id, U.name as '구매한 사람', O.name as '제품이름', O.price '제품가격',O.count as '구매개수',
SUM(O.price * O.count) OVER (PARTITION BY U.id)  '가격총합'
from userTbl U
inner join orderTbl O
on O.userid = U.id
where O.userid LIke 'k%'
order by U.name;

 

  • GROUP BY -- 행이 집약되기 때문에 세부데이터를 볼 수 없다.
    • GROUP BY U.id 를 묶어주니까   O.name, O.price, O.count를 출력할 수 없다.
    • 만약 O.name얘네들을 같이 선택하면   error code 1055 GROUP BY
    • [선택 목록, 조건 또는 목록이 절에 이름이 지정되지 않은 집계되지 않은 열을 참조하는 쿼리를 허용하지 않습니다
      •  U.id로 그룹화 되었기 때문에 U.어쩌구 (U.name은 출력이 되니까..)를 제외한 애들(O.어쩌구)은 쿼리 허용이 안되는 느낌이다 

GROUP BY

 

  • PARTITION BY  (행이 집약되지 않기 때문에 세부 데이터를 볼 수 있음.) 
    • U.id로 파티션을 나눴음에도,   O.name, O.price, O.count 에 접근해서 출력할 수 있다!
    • 가격 총합은 U.id로 묶인 결과가 계속 출력되고 있다. 

PARTITION BY - WINDOW FUNCTION

 

 

✔️ GROUP BY로도  PARTITION BY의 결과처럼   <제품의 세부 내용> 을 출력하는건 안될까? 

당연히 된다.  ---   그룹의 기준을 두개로 설정해주면 된다 (O.id, U.id )

 

 

유저의 아이디와 주문아이디로 그룹이 묶일테니 결과가 똑같을수도 있으려나??

당연히 결과는 똑같지 않다!!!!!

→ 결과이미지를 보면 알겠지만 가격 총합이 유저아이디/주문아이디로 그룹화되어  각그룹(유저의 주문번호당)의 총합으로 출력이 되는 것을 확인 할 수 있다. 

 

-- group by 
select U.id, U.name as '구매한사람', O.name as '제품이름', O.price '제품가격',O.count as '구매개수',
SUM(O.price * O.count) as '가격총합'
from userTbl U
inner join orderTbl O
on O.userid = U.id
where O.userid LIke 'k%'
group by O.id, U.id
order by U.name;

 

 

이결과까지 봤으니 더욱더 GROUP BY와 PARTITION BY의 차이점을 명확하게 알 수 있을것이라 생각한다.. 

 

잠 자러 가야지!

 

 

 


 

References