Q.
온라인 판매테이블과오프라인 판매테이블이 있을 때 이 둘을 통합하라.
온라인 판매 테이블과 오프라인 판매 테이블의 차이점은 user_id의 유무뿐인 문제
SELECT
#3
TRIM(SALES_DATE) SALES_DATE
, PRODUCT_ID
, IF(USER_ID = -1, NULL, USER_ID) USER_ID #2
, SUM(SALES_AMOUNT) SALES_AMOUNT
FROM
(
SELECT *
FROM ONLINE_SALE ONL
WHERE YEAR(SALES_DATE) = 2022 AND MONTH(SALES_DATE) = 3
UNION ALL #1
SELECT OFFLINE_SALE_ID, -1, PRODUCT_ID, SALES_AMOUNT, SALES_DATE
FROM OFFLINE_SALE OFL
WHERE YEAR(SALES_DATE) = 2022 AND MONTH(SALES_DATE) = 3
) A
GROUP BY
ONLINE_SALE_ID, PRODUCT_ID, USER_ID
ORDER BY
1
, 2
, 3
;
만 해주면 되는 간단한 문제이다.
다만 테스트케이스에는 없지만 하루에 여러 판매데이터가 있을 경우 GROUP BY를 하지 않을 경우 오답이 된다.
문제에선 GROUP BY를 하지 않아도 정답이지만 문제의 취지에 맞춰 생각하면 GROUP BY를 해주는게 맞다고 생각한다.
그리고 성능면에서 두가지를 얘기해보자면
1. UNION보단 UNION ALL의 부하가 더 적다. UNION은 중복 검사를 하기 때문. 이 문제에선 온오프라인 판매 데이터가 중복될 일은 없으니 UNION ALL을 사용하는 것이 바람직하다.
(여담으로 UNION ALL이 가능한 테이블이라면 한 테이블로 존재하는 것이 효율적이다.)
2. '2022년 3월'을 찾는 WHERE절을 위 아래 쿼리에 총 두번 썼는데, 이와 같이 서브쿼리 안에서 행 수를 줄여서 나가는 것이 일반적으로 좋다.
정확히는 WHERE과 같은 필터링 작업 시 인덱스를 사용해야 하는데 UNION ALL과 같은 연산은 임시테이블을 생성한다. 이런 임시 테이블에는 인덱스가 적용되지 않기 때문에 인덱스를 사용할 수 있는 변형 전 테이블에서 필터링 작업을 해야한다.