Question
문제 설명
CART_PRODUCTS 테이블은 장바구니에 담긴 상품 정보를 담은 테이블입니다. CART_PRODUCTS 테이블의 구조는 다음과 같으며, ID, CART_ID, NAME, PRICE는 각각 테이블의 아이디, 장바구니의 아이디, 상품 종류, 가격을 나타냅니다.
NAME | TYPE |
ID | INT |
CART_ID | INT |
NAME | VARCHAR |
PRICE | INT |
데이터 분석 팀에서는 우유(Milk)와 요거트(Yogurt)를 동시에 구입한 장바구니가 있는지 알아보려 합니다. 우유와 요거트를 동시에 구입한 장바구니의 아이디를 조회하는 SQL 문을 작성해주세요. 이때 결과는 장바구니의 아이디 순으로 나와야 합니다.
예를 들어 CART_PRODUCTS 테이블이 다음과 같다면
CART_PRODUCTS 테이블
ID | CART_ID | NAME | PRICE |
1630 | 83 | Cereal | 3980 |
1631 | 83 | Multipurpose Supply | 3900 |
5491 | 286 | Yogurt | 2980 |
5504 | 286 | Milk | 1880 |
8435 | 448 | Milk | 1880 |
8437 | 448 | Yogurt | 2980 |
8438 | 448 | Tea | 11000 |
20236 | 1034 | Yogurt | 2980 |
20237 | 1034 | Butter | 4890 |
- 83번 장바구니에는 Milk와 Yogurt가 모두 없습니다.
- 286번 장바구니에는 Milk와 Yogurt가 모두 있습니다.
- 448번 장바구니에는 Milk와 Yogurt가 모두 있습니다.
- 1034번 장바구니에는 Milk는 없고 Yogurt만 있습니다.
따라서 SQL 문을 실행하면 다음과 같이 나와야 합니다.
CART_ID |
286 |
448 |
Solve
글을 작성하게 된 이유, 다양한 풀이법이 있다.
-- 풀이 1
SELECT y.cart_id
from (select cart_id from cart_products where name = 'Yogurt') as y
join (select cart_id from cart_products where name = 'Milk') as m
on y.cart_id = m.cart_id
group by y.cart_id
order by y.cart_id
풀이 1. 요거트를 구매한 아이디의 테이블과, 우유를 구매한 테이블을 inner join 하는 풀이법
-- 풀이 2 : cross join
SELECT distinct P1.CART_ID
FROM CART_PRODUCTS P1
CROSS JOIN CART_PRODUCTS P2
ON P1.CART_ID = P2.CART_ID AND P1.NAME = 'Milk' AND P2.NAME = 'Yogurt'
풀이 2. 같은 테이블을 cross join, 이 때 한 쪽은 요거트를 구입하고 다른 한 쪽은 우유를 구입
첫번째 풀이법과 같은 맥략이지만 inner join이 아닌 cross join을 사용했다.
-- 풀이 3 : self join
SELECT distinct o.CART_ID
from CART_PRODUCTS o, CART_PRODUCTS n
where o.CART_ID = n.CART_ID and o.NAME = "Milk" and n.NAME = "Yogurt"
order by o.CART_ID
풀이 3. cross join과 비슷한 맥락의 self join
-- 풀이 4 : group_concat
select cart_id
from cart_products
group by cart_id
having group_concat(name) like '%milk%'
and group_concat(name) like '%yogurt%'
order by cart_id
풀이 4. group_concat 으로 그룹별 조건을 만들어 엮어주는 풀이법
사실 group_concat은 사용해 본 경험이 없어서 용례를 더 찾아보고 정리해 볼 예정이다.
-- 풀이 5 : in, distinct
SELECT CART_ID
FROM CART_PRODUCTS
WHERE NAME IN ('Milk', 'Yogurt')
GROUP BY CART_ID
HAVING COUNT(DISTINCT(NAME)) >= 2
ORDER BY CART_ID
풀이 5. having 절에 집계함수를 이용
우유 혹은 요거트를 산 데이터들 중, cart_id로 그룹핑했을 때, name이 다른 것이 2개 이상일 때
첫 접근은 풀이 1번으로 접근했는데 뭔가 더 간결한 코드는 없을까 고민했다.
풀이 5번은 disscussion에서 찾은 코드인데 가장 간결하고 재미있던 코드였다.
Source
https://school.programmers.co.kr/learn/courses/30/lessons/62284
'Study > SQL' 카테고리의 다른 글
HackerRank | 정규표현식 | weather observation station 6 ~ 11 (0) | 2023.07.16 |
---|---|
MySQL | 프로그래머스 | 상품을 구매한 회원 비율 구하기 (0) | 2023.04.19 |
회고 | 카카오 모빌리티 SQL 코딩테스트 (0) | 2023.03.14 |
MySQL | 프로그래머스 | 입양 시각 구하기(2) | Recursive CTE (0) | 2023.03.08 |
MySQL | 프로그래머스 | 즐겨찾기가 가장 많은 식당 정보 출력하기 (0) | 2023.03.08 |