본문 바로가기

algorithm

[programmers] MySQL - Lv.4 오프라인/온라인 판매 데이터 통합하기 (select)

문제

 

 

 

 

풀이

 

SELECT date_format(a.sales_date, '%Y-%m-%d') sales_date, 
       a.product_id, a.user_id, a.sales_amount
from (select online_sale_id, user_id, product_id, sales_amount, sales_date 
      from online_sale 
      union all 
      select offline_sale_id, null, product_id, sales_amount, sales_date 
      from offline_sale) a
where month(a.sales_date) = 3
order by sales_date, a.product_id, a.user_id

 

 

 

노트

 

이 문제는 UNION을 사용해서 풀어내는 문제이다.

두 개의 테이블의 컬럼을 잘 살펴보면 online_sale 테이블의 user_id를 제외한 나머지 컬럼이 모두 동일하고, 

JOIN을 사용해서 문제를 풀어내기에는 온라인과 오프라인이라는 판매처가 달라 컬럼이 겹치더라도 JOIN으로 테이블을 묶어낼 수 없다.

 

SQL에서 합집합은 'A UNION B'라고 표현하지만 A나 B는 실제로 SELECT 명령이다.

각 SELECT 명령에서 전체 데이터를 반환하는 애스터리스크( * )를 사용하지 않고 집합의 요소가 될 데이터를 서로 맞춰주면 UNION으로 실행할 수 있는 쿼리가 완성된다. 

UNION을 사용할 때 각각의 SELECT 명령의 열의 개수와 자료형은 서로 일치해야 하며, 열 구성이 다른 테이블은 UNION으로 묶을 수 없다.

UNION을 사용할 때에는 두 개의 SELECT 명령을 하나의 명령으로 합치는 만큼 세미콜론( ; )은 맨 나중에 붙여야 한다.

또한, UNION을 사용할 때 각 SELECT 명령에 ORDER BY를 지정할 수 없고, 마지막 SELECT 명령에만 지정이 가능하다.

UNION을 사용해서 합집합을 만들어낼 때 두 SELECT 명령의 교집합이 되는 부분은 중복이 제거되어 하나의 값만 반환하게 되는데, 중복을 제거하지 않고 2개의 SELECT 명령의 결과를 그냥 합치고 싶을 때는 UNION ALL을 사용하면 된다.

 

이 문제에서 OFFLINE_SALE 테이블은 USER_ID가 없기 때문에 문제를 보면 'OFFLINE_SALE 테이블의 판매 데이터의 USER_ID 값은 NULL로 표시해 주세요' 라 쓰여있는 것을 확인할 수 있는데, 이는 컬럼명을 NULL로 표기하면 된다.

즉, 이 문제에서는 중복을 제거하지 않고 합집합을 만들어내 문제를 풀어내야 하기 때문에 UNION ALL을 사용하면 된다.