우유와 요거트가 담긴 장바구니

하루히즘·2021년 5월 4일
0

프로그래머스

목록 보기
4/17

설명

프로그래머스의 우유와 요거트가 담긴 장바구니 문제다.

장바구니 테이블(레코드 id, 장바구니 id, 항목 이름, 가격)이 있을 때 두 상품을 담고 있는 레코드의 장바구니 id를 반환하는 문제다.

풀이

객체지향 언어였다면 자료구조 안에 두 상품이 있는지 확인하면 되겠지만 테이블에서는 한 레코드에 하나의 상품만 담아둘 수 있기 때문에 불가능하다. 대신 한 상품이 있는 장바구니의 집합과 다른 상품이 있는 장바구니의 집합을 JOIN한다면 두 상품이 담긴 레코드를 조회할 수 있을 것이다.

# 중복되는 장바구니 ID가 있기 때문에 DISTINCT로 중복 제거.
SELECT DISTINCT MILK_CART.CART_ID
FROM (
    # 'Milk'가 담긴 장바구니 레코드 조회.
    SELECT * 
    FROM CART_PRODUCTS
    WHERE NAME="Milk"
    ) AS MILK_CART
JOIN (
    # 'Yogurt'가 담긴 장바구니 레코드 조회.
    SELECT *
    FROM CART_PRODUCTS
    WHERE NAME="Yogurt"
    ) AS YOGURT_CART
# 장바구니 ID로 JOIN하여 'Milk'와 'Yogurt'가 담긴 장바구니를 조회.
ON MILK_CART.CART_ID=YOGURT_CART.CART_ID   
# 장바구니 ID 순으로 정렬하여 출력.
ORDER BY MILK_CART.CART_ID

처음에는 왜 중복되는 장바구니 ID가 출력되는지 이해를 못했는데 Milk나 Yogurt는 장바구니에 여러 개가 담겨있을 수 있기 때문이다. 실제로 JOIN된 데이터를 출력시켜보면 아래와 같다.
맨 마지막 레코드를 보면 왼쪽의 MILK_CART 테이블에 같은 ID(20497)의 레코드가 두 개 있는것을 볼 수 있는데 이는 YOGURT_CART 테이블에 해당 CART_ID(1048)의 레코드가 두 개(20491, 20503) 있기 때문이다. 비슷하게 같은 ID(8437)의 YOGURT_CART 레코드도 두 개가 존재하는데 이는 MILK_CART 테이블에 해당 CART_ID(448)의 레코드가 두 개(8454, 8435) 있기 때문이다.

문제에서 요구하는 것은 장바구니의 갯수기 때문에 중복된 레코드는 GROUP BY로 묶어서 출력할 수 있다. 해당 방식의 풀이는 아래와 같다.

SELECT MILK_CART.CART_ID
FROM (
    SELECT * 
    FROM CART_PRODUCTS
    WHERE NAME="Milk"
    ) AS MILK_CART
JOIN (
    SELECT *
    FROM CART_PRODUCTS
    WHERE NAME="Yogurt"
    ) AS YOGURT_CART
ON MILK_CART.CART_ID=YOGURT_CART.CART_ID  
GROUP BY MILK_CART.CART_ID 
ORDER BY MILK_CART.CART_ID

후기

SQL 문제는 딱히 풀이랄 건 없지만 문법을 아는 것이 중요한 것 같다. 특히 서브쿼리가 가능한지 알지 못했다면 아마 지난번처럼 WITH 키워드까지 활용해야 했을지도 모른다.

profile
YUKI.N > READY?

0개의 댓글