SQL 'WINDOW' 이것까지만 알아도 다룰줄 아는 사람

아뇨 민균데요·2025년 5월 20일
0

윈도우 함수란?

  • 데이터베이스에서 데이터를 그룹별로 나누어 정리하거나, 누적합, 순위, 비율 등을 계산할 때 사용하는 아주 유용한 도구.
  • 쉽게 말하면, 데이터의 일부분을 "창문(window)"처럼 설정해서 그 안에서 데이터를 계산하는 함수라고 생각하면 됨.

1. 윈도우 함수의 기본 구조

window_function(argument) 
OVER (PARTITION BY 그룹 기준 컬럼 ORDER BY 정렬 기준)
  • window_function: 실행할 함수 이름 (SUM, AVG, RANK 등)
  • PARTITION BY: 데이터를 나눌 기준 (예: 반별, 팀별, 지역별 등)
  • ORDER BY: 각 그룹 내에서 데이터를 정렬할 기준 (예: 점수, 매출액 등)

2. 윈도우 함수의 예시

예시 1: 반별 성적 순위

SELECT 학생이름,, 점수,
       RANK() OVER (PARTITION BYORDER BY 점수 DESC) AS 순위
FROM 성적표;
  • 각 반별로 점수를 내림차순으로 정렬하고 순위를 매김
  • 같은 점수를 가진 학생이 있으면 같은 순위로 표시

예시 2: 음식점 매출 비율 계산

SELECT 음식점, 매출액,
       매출액 / SUM(매출액) OVER (PARTITION BY 음식종류) * 100 AS 매출비율
FROM 음식점매출;
  • 각 음식점의 매출이 해당 음식 종류의 전체 매출에서 차지하는 비율을 계산

예시 3: 누적합 계산

SELECT 음식점, 매출액,
       SUM(매출액) OVER (PARTITION BY 음식종류 ORDER BY 매출액) AS 누적매출
FROM 음식점매출;
  • 각 음식점의 매출을 음식 종류별로 누적하여 합산

3. 윈도우 함수의 종류

  • RANK(): 동점이 있으면 같은 순위, 다음 순위를 건너뜀
  • ROW_NUMBER(): 모든 행에 일렬로 순위를 매김 (동점 없음)
  • DENSE_RANK(): 동점이 있으면 같은 순위, 다음 순위를 건너뛰지 않음
  • SUM(): 그룹 내에서 누적합 계산
  • AVG(): 그룹 내에서 평균 계산
  • COUNT(): 그룹 내의 행 개수 계산

4. 조금 더 복잡한 예시 (실습 문제)

SELECT 음식종류, 음식점,
       RANK() OVER (PARTITION BY 음식종류 ORDER BY 주문건수 DESC) AS 순위,
       주문건수
FROM (SELECT 음식종류, 음식점, COUNT(*) 주문건수
      FROM 음식점주문
      GROUP BY 음식종류, 음식점) t
WHERE 순위 <= 3
ORDER BY 음식종류, 순위;
  • 각 음식 종류별로 주문 건수가 많은 상위 3개 음식점을 조회하는 예시

이렇게 열심히 풀어 설명해도,,, 해보지 않으면 절대 모른다

그래서 예제도 준비했다. 푸는데 좀 시간이 걸릴 것이니 여유 있는 날 심심풀이 땅콩으로 풀길 바란다.


🌟 윈도우 함수 실습 문제

문제:
온라인 쇼핑몰에서 고객들이 주문한 데이터가 아래와 같이 있다고 가정해보자. 각 고객이 얼마나 많이 주문했는지 순위를 매기고, 각 고객의 누적 주문 금액도 계산해보자.

📝 데이터 (order_history 테이블)

customer_idorder_amount
C00110000
C00215000
C00320000
C00412000
C00518000
C00130000
C00225000
C00310000
C00420000
C00515000

🔍 요구사항:

  1. 각 고객의 총 주문 금액을 계산하시오.
  2. 각 고객의 주문 금액 순위를 계산하시오 (금액이 큰 순서).
  3. 각 고객의 누적 주문 금액을 계산하시오 (금액이 큰 순서).

💡 출력 예시:

customer_idtotal_amountrankcumulative_amount
C00330000130000
C00533000263000
C002400003103000
C001400003143000
C004320005175000

이 문제를 풀기 위해서는 SUM(), RANK()와 같은 윈도우 함수를 사용 해야함.


🔍 실습 문제 해설 (SQL)

-- 1. 각 고객의 총 주문 금액 계산
SELECT 
  customer_id, 
  SUM(order_amount) AS total_amount
FROM order_history
GROUP BY customer_id;

-- 2. 총 주문 금액에 따른 순위 계산
SELECT 
  customer_id, 
  total_amount,
  RANK() OVER (ORDER BY total_amount DESC) AS rank
FROM (
  SELECT 
    customer_id, 
    SUM(order_amount) AS total_amount
  FROM order_history
  GROUP BY customer_id
) a;

-- 3. 누적 주문 금액 계산
SELECT 
  customer_id, 
  total_amount,
  RANK() OVER (ORDER BY total_amount DESC) AS rank,
  SUM(total_amount) OVER (ORDER BY total_amount DESC) AS cumulative_amount
FROM (
  SELECT 
    customer_id, 
    SUM(order_amount) AS total_amount
  FROM order_history
  GROUP BY customer_id
) b
ORDER BY cumulative_amount;

💡 예상 출력 결과:

customer_idtotal_amountrankcumulative_amount
C00330000130000
C00533000263000
C002400003103000
C001400003143000
C004320005175000
profile
this man을 꿈 속에서 보신 적이 있으신가요?

0개의 댓글