CodeGym /행동 /SQL SELF /윈도우 함수랑 집계 함수 비교: GROUP BY vs PARTIT...

윈도우 함수랑 집계 함수 비교: GROUP BY vs PARTITION BY

SQL SELF
레벨 30 , 레슨 0
사용 가능

처음 보면 윈도우 함수랑 집계 함수가 비슷해 보여. 둘 다 합계, 평균, 순위 같은 계산을 하니까. 근데 실제로는 꽤 다르거든? 그 차이를 제대로 파헤쳐보자.

집계 함수 (GROUP BY)

집계 함수는 이렇게 동작해:

  • 지정한 컬럼으로 행들을 그룹핑해.
  • 그룹핑 후에 각 그룹이 결과에서 한 줄로 바뀌어.
  • 예시: 각 지역별로 총 매출을 알고 싶을 때.
SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;

특징: GROUP BY는 데이터를 "압축"해. 그룹에 속한 모든 행이 사라지고, 집계 결과만 남아.

윈도우 함수 (PARTITION BY)

윈도우 함수는 반대로:

  • 원래 데이터 구조를 그대로 유지해 (행이 사라지거나 압축되지 않아!).
  • "윈도우" — 논리적으로 나눈 그룹 안에서 계산을 할 수 있어.

예시: 각 도시가 자기 지역 전체 매출에서 차지하는 비율을 알고 싶은데, 데이터는 다 남겨두고 싶을 때.

SELECT
    region,
    city,
    sales,
    SUM(sales) OVER (PARTITION BY region) AS total_sales_by_region
FROM sales_data;

특징: 윈도우 함수를 쓰면 행이 사라지지 않고, 각 행에 계산된 값이 추가돼.

예시: SUM() + GROUP BY vs SUM() + PARTITION BY

차이를 더 확실히 보려면, SUM()이 두 경우에 어떻게 동작하는지 보자. 예를 들어, sales_data 테이블이 이렇게 있다고 치자:

region city sales
North CityA 100
North CityB 150
South CityC 200
South CityD 250

GROUP BY로 합계 구하기

각 지역별로 총 매출을 알고 싶어:

SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;

결과는 이렇게 나와:

region total_sales
North 250
South 450

무슨 일이 일어났냐면: region별로 행이 그룹핑되고, 각 그룹이 매출 합계 한 줄로 "압축"됐어.

PARTITION BY로 합계 구하기

이번엔 윈도우 함수로 똑같이 해보자:

SELECT
    region,
    city,
    sales,
    SUM(sales) OVER (PARTITION BY region) AS total_sales_by_region
FROM sales_data;

결과:

region city sales total_sales_by_region
North CityA 100 250
North CityB 150 250
South CityC 200 450
South CityD 250 450

무슨 일이 일어났냐면: PARTITION BY는 행을 "압축"하지 않아. 대신 각 윈도우(여기선 지역별) 안에서 합계를 계산해서 각 행에 붙여줘.

GROUP BYPARTITION BY 언제 써야 할까?

GROUP BY: 최종 리포트에 딱이야

GROUP BY는 데이터 양을 줄이고, 그룹별로 결과만 뽑고 싶을 때 좋아. 예를 들면:

  • 월별 총 매출.
  • 상품 카테고리별 주문 개수 세기.

예시:

SELECT category, COUNT(*) AS total_orders
FROM orders
GROUP BY category;

PARTITION BY: 분석이나 상세 데이터에 최고

PARTITION BY는 모든 행을 남겨두고, 각 행마다 뭔가 계산해서 붙이고 싶을 때 써. 예를 들면:

  • 카테고리별로 각 상품이 차지하는 매출 비율 구하기.
  • 각 그룹 안에서 행 번호 매기기.

매출 비율 계산 예시:

SELECT
    category,
    product,
    sales,
    ROUND(
        (sales * 100.0) / SUM(sales) OVER (PARTITION BY category),
        2
    ) AS sales_percentage
FROM sales_data;

예시: 여러 윈도우 함수 한 번에 쓰기

윈도우 함수의 장점 중 하나는 여러 계산을 한 쿼리에서 할 수 있다는 거야. 예를 들어:

SELECT
    region,
    city,
    sales,
    SUM(sales) OVER (PARTITION BY region) AS total_sales,
    RANK() OVER (PARTITION BY region ORDER BY sales DESC) AS sales_rank
FROM sales_data;

결과:

region city sales total_sales sales_rank
North CityB 150 250 1
North CityA 100 250 2
South CityD 250 450 1
South CityC 200 450 2

GROUP BY보다 윈도우 함수가 좋은 점

원본 데이터 보존: GROUP BY는 행을 "압축"하지만, 윈도우 함수는 테이블 구조를 그대로 남겨둬.

한 쿼리에서 여러 계산 가능: PARTITION BYORDER BY를 다르게 줘서 여러 윈도우 함수를 한 번에 쓸 수 있어.

분석의 유연성: 윈도우 함수로 누적 합계, 순위, 비율 계산 등 원하는 대로 분석할 수 있어.

유연성 예시

여러 함수 조합해보자:

SELECT
    region,
    city,
    sales,
    SUM(sales) OVER (PARTITION BY region) AS total_sales,
    AVG(sales) OVER (PARTITION BY region) AS avg_sales,
    RANK() OVER (PARTITION BY region ORDER BY sales DESC) AS rank
FROM sales_data;

결과:

region city sales total_sales avg_sales rank
North CityB 150 250 125.0 1
North CityA 100 250 125.0 2
South CityD 250 450 225.0 1
South CityC 200 450 225.0 2

제한사항과 흔한 실수

많이 하는 실수 중 하나가, 데이터를 "압축"해야 할 때 PARTITION BY를 쓰는 거야. 예를 들어, 이 쿼리 대신:

SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;

이렇게 쓰는 경우가 있어:

SELECT
    region,
    SUM(sales) OVER (PARTITION BY region) AS total_sales
FROM sales_data;

근데 이렇게 하면 모든 행이 다 나와. 데이터 양이 줄지 않지 (항상 원하는 결과가 아니야).

이제 GROUP BY랑 윈도우 함수 언제 써야 할지 확실히 알겠지? 이건 마치 망치랑 드라이버 중에 뭐 쓸지 고르는 거랑 비슷해. 둘 다 못 박을 수 있지만... 방식이 달라!

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION