CodeGym /행동 /SQL SELF /OVER() 문법과 주요 특징

OVER() 문법과 주요 특징

SQL SELF
레벨 29, 레슨 2
사용 가능

OVER()는 SQL한테 어떤 행 집합에 윈도우 함수를 적용할지 알려주는 명령어야. 쉽게 말해서, 데이터에 "윈도우"를 어떻게 정할지 지정하는 방법이지. 예를 들어, 방에 사람들이 가득 있는데, 바닥의 각 평방미터마다 몇 명이 서 있는지 세고 싶다고 해보자. OVER()는 우리가 방의 어느 부분에 집중할지 정해주는 거야. 다시 말해서, 함수가 어떤 행 집합에 적용될지 지정하는 거지.

OVER() 연산자는 윈도우 함수랑만 같이 써서, 한 개 또는 여러 테이블의 행에 연산을 할 수 있어. 이때 데이터 그룹화는 안 해.

문법:

윈도우_함수() OVER (
    [PARTITION BY ...]
    [ORDER BY ...]
    [ROWS/RANGE ...]
)

여기서:

  • PARTITION BY — 데이터 집합을 논리적인 그룹으로 나눔
  • ORDER BY — 각 그룹 안에서 행의 순서를 정함
  • ROWS/RANGE — "윈도우"의 크기를 지정함 (예: 현재 행 + 다음 1개)

예시: OVER() 파라미터 없이 쓰기

OVER()를 아무 옵션 없이 쓰면, 그 앞에 있는 함수가 전체 데이터 집합에 적용된다는 뜻이야.

SELECT
    employee_id,
    salary,
    ROW_NUMBER() OVER () AS row_num -- ROW_NUMBER()는 결과의 모든 행에 적용됨
FROM employees;

무슨 일이 일어나냐면?

  1. ROW_NUMBER()가 각 행에 고유 번호를 붙여줘.
  2. OVER()에 아무 옵션도 없으니까, employees 테이블의 모든 행을 하나의 집합으로 처리해.

결과:

employee_id salary row_num
1 50000 1
2 60000 2
3 55000 3

PARTITION BY로 그룹 나누기

좋아, 이제 회사 전체가 아니라 각 부서 안에서 직원 번호를 매기고 싶다고 해보자. 이럴 때 PARTITION BY가 등장해.

OVER() 안의 PARTITION BY는 데이터를 그룹(또는 "섹션")으로 나눠. 각 그룹마다 함수가 따로 값을 계산해. 만약 ROW_NUMBER()가 웨이터라면, 각 "테이블"(섹션)마다 번호를 새로 매기는 거지.

예시: PARTITION BY 사용

SELECT
    department_id,
    employee_id,
    salary,
    ROW_NUMBER() OVER (PARTITION BY department_id) AS row_num
FROM employees;

무슨 일이 일어나냐면?

  1. employees 테이블의 데이터가 department_id 값으로 그룹화돼.
  2. 각 그룹 안에서 ROW_NUMBER()로 행마다 순번을 매겨.

결과:

department_id employee_id salary row_num
1 1 50000 1
1 3 55000 2
2 2 60000 1

ORDER BY로 순서 정하기

이제 좀 더 구조를 추가해보자. 그냥 번호만 매기는 게 아니라, 예를 들어 가장 높은 연봉부터 순번을 매기고 싶을 수도 있잖아? 이럴 때 ORDER BY를 쓰면 돼.

ORDER BY는 윈도우 함수가 행을 어떤 순서로 처리할지 정해줘.

예시: OVER() 안에 ORDER BY 쓰기

SELECT
    department_id,
    employee_id,
    salary,
    RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank
FROM employees;

무슨 일이 일어나냐면?

  1. 데이터가 (PARTITION BY department_id)로 그룹화돼.
  2. 각 그룹 안에서 행이 연봉 내림차순(ORDER BY salary DESC)으로 정렬돼.
  3. 정렬된 순서대로 각 행에 랭크가 매겨져.

결과:

department_id employee_id salary rank
1 3 55000 1
1 1 50000 2
2 2 60000 1

윈도우 함수 여러 개 조합하기

SQL에서는 한 쿼리에서 여러 윈도우 함수를 쓸 수 있어. 각 함수마다 자기만의 규칙으로 동작하지! 마치 한 방에서 음악도 틀고, 사람 수도 세는 것처럼, 각각 따로 돌아가는 거야!

예시: 여러 윈도우 함수

SELECT
    department_id,
    employee_id,
    salary,
    ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num,
    AVG(salary) OVER (PARTITION BY department_id) AS avg_salary
FROM employees;

무슨 일이 일어나냐면?

  1. ROW_NUMBER()는 각 그룹에서 연봉 내림차순으로 행에 번호를 매겨.
  2. AVG()는 각 그룹의 평균 연봉을 계산해.

결과:

department_id employee_id salary row_num avg_salary
1 3 55000 1 52500
1 1 50000 2 52500
2 2 60000 1 60000

실생활 예시

OVER()랑 윈도우 함수는 진짜 여러 상황에서 써! 예를 들면:

  • 판매 분석: 각 카테고리별로 상품을 판매량 순위로 매기기
  • 랭킹: 각 그룹에서 학생들의 평균 점수로 순위 정하기
  • 시계열: 시간별 누적 판매 합계 구하기

판매 분석 예시:

SELECT
    category_id,
    product_id,
    product_name,
    SUM(sales) OVER (PARTITION BY category_id ORDER BY sales DESC) AS cumulative_sales
FROM products;

윈도우 함수 쓸 때 자주 하는 실수

  1. PARTITION BY 안 쓰기

PARTITION BY를 안 쓰면, 윈도우 함수가 테이블 전체에 적용돼. 그룹별로 나눠서 결과를 기대했다면, 예상과 다르게 나올 수 있어.

💡 테이블을 어떻게 나눌지(예: 사용자, 주문, 카테고리 등) 명확하게 PARTITION BY로 지정해줘!


  1. ORDER BY에서 데이터 타입 잘못 쓰기

윈도우 함수 안의 ORDER BY는 데이터 타입에 민감해. 만약 날짜 필드를 VARCHAR로 저장했다면, 정렬이 알파벳 순서로 될 수도 있고, 시간 순서가 아닐 수도 있어.

💡 정렬 전에 그런 필드는 꼭 DATE, INTEGER 등 필요한 타입으로 변환해!

  1. ROWS BETWEEN 잘못 쓰기

윈도우 함수는 기본적으로 ROWS BETWEEN으로 범위를 정해. 만약 명확하게 범위를 지정 안 하면, RANGE가 적용돼서 예상보다 더 많은 행이 결과에 포함될 수 있어.

💡 누적 합계처럼 처음부터 현재 행까지 합치고 싶으면 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW를 써!

  1. NULL 처리 실수

윈도우 함수는 NULL을 다루는 방식이 다를 수 있어. 예를 들어, RANK()나 DENSE_RANK()는 NULL도 값으로 보고, 따로 랭크를 매겨.

💡 ORDER BY에서 NULLS LAST나 NULLS FIRST를 써서 NULL이 어디에 올지 정해!

  1. 일반 집계 함수 대신 윈도우 집계 함수 쓰기

가끔 SUM() OVER(...) 같은 윈도우 집계 함수를 GROUP BY로 충분한 상황에서도 써서, 쿼리가 복잡해지고 느려질 수 있어.

💡 행별 상세 정보가 꼭 필요할 때만 윈도우 함수를 써!

2
과제
SQL SELF, 레벨 29, 레슨 2
잠금
테이블의 행 번호 매기기
테이블의 행 번호 매기기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION