CodeGym /행동 /SQL SELF /윈도우 함수 사용할 때 흔히 하는 실수들

윈도우 함수 사용할 때 흔히 하는 실수들

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

이제 윈도우 함수 쓸 때 생길 수 있는 어려움에 대해 얘기해보자. 프로그래밍(그리고 인생)에서 남의 실수에서 배우는 게 최고잖아. 초보자뿐만 아니라 가끔은 경험 많은 개발자들도 저지르는 흔한 실수들을 같이 살펴보고, 어떻게 피할 수 있는지 배워보자.

실수 №1: PARTITION BY 잘못 쓰기

가장 자주 하는 실수 중 하나는 PARTITION BY 파라미터를 빼먹거나 잘못 지정하는 거야. 특히 데이터를 그룹별로 나누고 싶을 때 더 그렇지. 이걸 안 쓰면 PostgreSQL이 모든 행을 하나의 큰 그룹으로 보고, 결과가 기대와 완전 다르게 나올 수 있어.

예를 들어, sales라는 테이블이 있고, 여기에 판매 데이터가 들어있다고 해보자:

id region month total
1 North 2023-01 1000
2 South 2023-01 800
3 North 2023-02 1200
4 South 2023-02 900

각 지역별로 월별 누적 합계(SUM())를 구하고 싶다고 해보자. 이렇게 쿼리를 쓸 수 있어:

SELECT
    region,
    month,
    SUM(total) OVER (ORDER BY month) AS running_total
FROM 
    sales;

결과:

region month running_total
North 2023-01 1000
South 2023-01 1800
North 2023-02 3000
South 2023-02 3900

처음 보면 괜찮아 보이지만, 결과가 기대와 다르지? 누적 합계가 지역별로 계산된 게 아니라 모든 행을 한 번에 계산한 거야. PARTITION BY region를 빼먹은 게 문제지.

수정된 코드:

SELECT 
    region,
    month,
    SUM(total) OVER (PARTITION BY region ORDER BY month) AS running_total
FROM 
    sales;

결과:

region month running_total
North 2023-01 1000
North 2023-02 2200
South 2023-01 800
South 2023-02 1700

이제 제대로 됐지! 데이터가 지역별로 그룹화되고, 누적 합계도 각 지역마다 따로 계산돼.

실수 №2: ORDER BY 순서 잘못 지정하기

OVER() 안의 ORDER BY는 윈도우 내에서 행의 순서를 정해줘. 순서를 잘못 지정하면 결과가 엉뚱하게 나올 수 있어.

월별로 내림차순 정렬해서 누적 판매 합계를 구하고 싶다고 해보자. 이렇게 쿼리를 쓸 수 있어:

SELECT
    month,
    total,
    SUM(total) OVER (ORDER BY month DESC) AS running_total
FROM 
    sales;

결과:

month total running_total
2023-02 1200 1200
2023-02 900 2100
2023-01 1000 3100
2023-01 800 3900

겉보기엔 맞는 것 같지만, 잘 보면 행이 월별로 묶여 있고 누적 합계가 내림차순 정렬 때문에 제대로 안 됐어. 그래서 결과가 헷갈리게 나와.

수정 방법: ORDER BY 순서를 올바르게 지정해줘:

SELECT
    month,
    total,
    SUM(total) OVER (ORDER BY month ASC) AS running_total
FROM 
    sales;

실수 №3: 인덱스 없이 윈도우 함수 쓰기

윈도우 함수는 보통 데이터가 많을 때 쓰는데, 중요한 컬럼에 인덱스가 없으면 성능이 엄청 떨어질 수 있어.

예시: large_sales라는 테이블에 수백만 행이 있고, 판매 순위를 계산하고 싶다고 해보자:

SELECT
    id,
    total,
    RANK() OVER (ORDER BY total DESC) AS rank
FROM 
    large_sales;

데이터가 적으면 금방 끝나지만, 많으면 진짜 오래 걸릴 수 있어.

수정 방법: ORDER BY에 쓰는 컬럼에 인덱스를 추가해줘:

CREATE INDEX idx_total ON large_sales(total DESC);

이제 쿼리가 훨씬 빨라질 거야.

실수 №4: ROWS나 RANGE 윈도우 범위 헷갈리기

ROWS랑 RANGE 쓸 때, 이게 어떻게 윈도우 범위를 정하는지 잘 이해해야 해. 이걸 잘못 알면 결과가 이상하게 나올 수 있어.

예시: 이번 달과 이전 두 달의 이동 평균을 구하고 싶다고 해보자:

SELECT
    month,
    AVG(total) OVER (ORDER BY month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM 
    sales;

만약 ROWS 대신 RANGE를 쓰면:

SELECT
    month,
    AVG(total) OVER (ORDER BY month RANGE BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM 
    sales;

결과가 달라질 거야. RANGE는 값의 범위로 계산하고, ROWS는 행의 개수로 계산하거든.

실수 №5: 윈도우 함수 남발하기

한 쿼리에서 여러 번 윈도우 함수를 쓰면 계산이 중복되고, 성능도 떨어질 수 있어.

예시:

SELECT 
    id,
    total,
    SUM(total) OVER (PARTITION BY region) AS region_total,
    SUM(total) OVER (PARTITION BY region) / COUNT(total) OVER (PARTITION BY region) AS region_avg
FROM 
    sales;

여기서 SUM(total)이랑 COUNT(total)가 각 행마다 여러 번 계산돼.

수정 방법: 서브쿼리나 CTE를 써서 쿼리를 줄여보자:

WITH cte_region_totals AS (
    SELECT 
        region,
        SUM(total) AS region_total,
        COUNT(total) AS region_count
    FROM 
        sales
    GROUP BY 
        region
)
SELECT 
    s.id,
    s.total,
    t.region_total,
    t.region_total / t.region_count AS region_avg
FROM 
    sales s
JOIN 
    cte_region_totals t ON s.region = t.region;

실수 피하는 꿀팁

PARTITION BY랑 ORDER BY 꼭 확인하기: 윈도우가 제대로 지정됐는지 항상 체크해.

데이터에 인덱스 걸기: 특히 ORDER BY나 필터링 쓸 때는 필수야.

중복 계산엔 CTE 쓰기: 중복되는 계산 줄이려면 CTE가 좋아.

실행 계획 보기: EXPLAIN이나 EXPLAIN ANALYZE로 PostgreSQL이 쿼리를 어떻게 처리하는지 확인해봐.

실제 데이터로 테스트하기: 결과가 기대와 맞는지, 문제 없이 동작하는지 꼭 확인해봐.

2
과제
SQL SELF, 레벨 30, 레슨 4
잠금
ORDER BY를 윈도우 함수에서 사용하기
ORDER BY를 윈도우 함수에서 사용하기
1
설문조사/퀴즈
윈도우 프레임 설정하기, 레벨 30, 레슨 4
사용 불가능
윈도우 프레임 설정하기
윈도우 프레임 설정하기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION