프로그래머스 SQL 풀이 오답노트(9): JOIN, WITH

SeongGyun Hong·2025년 1월 31일

SQL

목록 보기
33/51

https://school.programmers.co.kr/learn/courses/30/lessons/133027

1. 내 쿼리

WITH FULL_ID AS (
    SELECT FLAVOR
    FROM FIRST_HALF
    UNION
    SELECT FLAVOR
    FROM JULY
),
FULL_JULY AS (
    SELECT FLAVOR AS FLAVOR, SUM(TOTAL_ORDER) AS TOTO
    FROM JULY
    GROUP BY FLAVOR
    )
SELECT FI.FLAVOR
FROM FULL_ID FI
LEFT JOIN (SELECT FLAVOR, TOTAL_ORDER AS FH_ORDER FROM FIRST_HALF) FH
ON FI.FLAVOR = FH.FLAVOR
LEFT JOIN (SELECT FLAVOR, TOTO AS J_ORDER FROM FULL_JULY) J
ON FI.FLAVOR = J.FLAVOR
ORDER BY (COALESCE(FH.FH_ORDER, 0) + COALESCE(J.J_ORDER, 0)) DESC
FETCH FIRST 3 ROWS ONLY;

그런데 ;; 생각해보니 굳이 위에처럼 WITH절을 두번 쓸 필요 없이
아래처럼 하는 것이 더 로직이 깔끔하고 좋아보인다.

2. 장원 쿼리

WITH FULL_ORDERS AS (
    SELECT FLAVOR, SUM(TOTAL_ORDER) AS TOTAL_ORDER
    FROM (
        SELECT FLAVOR, TOTAL_ORDER FROM FIRST_HALF
        UNION ALL
        SELECT FLAVOR, TOTAL_ORDER FROM JULY
    )
    GROUP BY FLAVOR
)
SELECT FLAVOR
FROM FULL_ORDERS
ORDER BY TOTAL_ORDER DESC
FETCH FIRST 3 ROWS ONLY;
  • UNION ALL 사용:
    UNION 대신 UNION ALL을 사용하여 중복 제거 작업을 피함.
    UNION은 중복을 제거하기 위해 추가적인 정렬 작업을 수행하지만, UNION ALL은 중복을 제거하지 않기 때문에 더 빠름(캬)
    본 문제에서는, FLAVOR와 TOTAL_ORDER를 합치는 과정에서 중복 제거를 필요로 하지 않으므로 UNION ALL이 더 적합함. (최적화 포인트)
    왜냐하면 이후에 어차피 group by로 한데 엮어줄 것이기 때문.

  • 하나의 CTE로 통합:
    FULL_ID와 FULL_JULY 두 개의 CTE를 하나의 CTE(FULL_ORDERS)로 통합.
    이렇게 하면 쿼리가 더 간결해지고, 데이터를 한 번만 스캔하므로 성능이 향상됨.(최적화 포인트)

  • COALESCE 제거:
    원래 쿼리에서는 COALESCE를 사용하여 NULL 값을 처리했지만, UNION ALL을 사용하고 하나의 CTE로 통합하면서 NULL 값이 발생하지 않으므로 COALESCE를 제거할 수 있음 (최적화 포인트)

  • ORDER BY 및 FETCH FIRST:
    최종적으로 TOTAL_ORDER를 기준으로 정렬하고 상위 3개의 FLAVOR를 선택함. 이건 이전 쿼리와 동일

profile
헤매는 만큼 자기 땅이다.

0개의 댓글