프로그래머스 SQL - 66번(IN 응용, GROUP BY)

yeyeyeyeye·2025년 8월 13일

🛒 SQL 문제: 우유(Milk)와 요거트(Yogurt)를 동시에 구입한 장바구니 찾기

데이터 분석 팀에서 우유와 요거트를 동시에 구입한 장바구니가 있는지 확인하려고 합니다.
아래 두 SQL문 중 어떤 것이 올바른지 비교해 봅시다.


쿼리 비교

1. 첫 번째 쿼리 ✅ (정답)

SELECT cart_id
FROM cart_products
WHERE name IN ('Milk') or name IN ('Yogurt')
GROUP BY cart_id
HAVING COUNT(DISTINCT name) >= 2
ORDER BY cart_id;
  • GROUP BY cart_id로 장바구니별 그룹화.

  • COUNT(DISTINCT name)으로 그 장바구니 안에 있는 서로 다른 상품 종류 수를 셈.

  • Milk와 Yogurt가 모두 있으면 DISTINCT name의 개수가 2가 되어 조건 만족.

2. 두 번째 쿼리 ❌ (오답)

SELECT cart_id
FROM cart_products
WHERE name IN ('Milk', 'Yogurt')
GROUP BY cart_id
HAVING COUNT(DISTINCT cart_id) >= 2
ORDER BY cart_id;
  • GROUP BY cart_id 후에는 그 그룹 안의 cart_id 값이 하나뿐.

  • 따라서 COUNT(DISTINCT cart_id)는 항상 1 → >= 2 조건을 만족할 수 없음.

  • 우리가 세야 하는 건 cart_id의 종류가 아니라 상품명(name)의 종류.

3. 정석 풀이

SELECT cart_id
FROM cart_products
WHERE name IN ('Milk', 'Yogurt')
GROUP BY cart_id
HAVING COUNT(DISTINCT name) = 2
ORDER BY cart_id;

4. 대안 풀이

1) 셀프 조인 방식

SELECT DISTINCT c1.cart_id
FROM cart_products c1
JOIN cart_products c2
  ON c1.cart_id = c2.cart_id
WHERE c1.name = 'Milk'
  AND c2.name = 'Yogurt'
ORDER BY c1.cart_id;

2) 조건 합 집계 방식

SELECT cart_id
FROM cart_products
GROUP BY cart_id
HAVING SUM(CASE WHEN name = 'Milk' THEN 1 ELSE 0 END) > 0
   AND SUM(CASE WHEN name = 'Yogurt' THEN 1 ELSE 0 END) > 0
ORDER BY cart_id;

정리
1) 집계 조건 필터에서는 COUNT(DISTINCT name)처럼 의미 있는 컬럼을 기준으로 세야 한다.

2) GROUP BY 후 COUNT(DISTINCT 그룹키)는 대부분 1이므로 조건 필터에 부적합.

3) 같은 문제를 다양한 방식(집계, 조인, 조건 합)으로 풀어보면 SQL 사고력이 빨라진다.

profile
안녕하세요? 데이터분석가 되고 싶어요.

0개의 댓글