https://school.programmers.co.kr/learn/courses/30/lessons/133027
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절을 두번 쓸 필요 없이
아래처럼 하는 것이 더 로직이 깔끔하고 좋아보인다.
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를 선택함. 이건 이전 쿼리와 동일