[SQL] 가구 판매 비중 높은 날 찾기

2026. 1. 13. 13:55코딩테스트

1. 문제 요약

이커머스 주문 데이터에서 다음 조건을 만족하는 날짜를 찾아야 한다.

  • 대상: 일별 전체 주문 수가 10개 이상인 날.
  • 조건: 그중 'Furniture(가구)' 카테고리 주문의 비율이 40% 이상인 날.
  • 출력: 날짜, 가구 주문 수, 가구 주문 비율(소수점 둘째 자리).
  • 정렬: 가구 주문 비율 내림차순, 날짜 오름차순.

2. 문제 해결 아이디어

이 문제의 핵심은 '전체 주문 수'와 '가구 카테고리 주문 수'를 각각 구해서 비율을 계산하는 것이다. 하나의 order_id 안에 여러 상품이 포함될 수 있으므로, 주문 건수를 셀 때는 중복을 제거하기 위해 DISTINCT를 사용해야 한다. 또한 집계된 결과(비율, 전체 주문 수)를 기준으로 데이터를 걸러내야 하므로 WHERE가 아닌 HAVING 절을 사용한다.

3. 정답 쿼리

SQL
 
SELECT
    order_date,
    -- 가구 카테고리의 고유 주문 번호 개수 계산
    COUNT(DISTINCT CASE WHEN category = 'Furniture' THEN order_id END) AS furniture,
    -- 가구 주문 비율 계산 (가구 주문 수 / 전체 주문 수 * 100)
    ROUND(COUNT(DISTINCT CASE WHEN category = 'Furniture' THEN order_id END) * 100.0 / COUNT(DISTINCT order_id), 2) AS furniture_pct
FROM
    records
GROUP BY
    order_date
HAVING
    -- 일별 고유 주문 수가 10건 이상
    COUNT(DISTINCT order_id) >= 10
    -- 가구 주문 비율이 40% 이상 (MySQL 허용 문법)
    AND furniture_pct >= 40
ORDER BY
    furniture_pct DESC,
    order_date ASC;

4. 상세 풀이

1) CASE WHEN을 이용한 조건부 카운트 가구 주문 수만 따로 세기 위해 CASE WHEN category = 'Furniture' THEN order_id END 구문을 사용했다. 이 구문은 카테고리가 가구인 경우에만 주문 ID를 반환하고, 나머지는 NULL로 처리한다. 여기에 COUNT(DISTINCT ...)를 씌워 중복 없는 가구 주문 건수를 구했다.

2) 비율 계산과 형 변환 비율을 구할 때는 (가구 주문 수 / 전체 주문 수) * 100 공식을 사용한다. 이때 정수끼리의 나눗셈이 되어 소수점이 버려지는 것을 방지하기 위해 100.0을 곱해 실수형으로 변환하여 계산했다. 마지막으로 ROUND(..., 2)를 사용해 소수점 둘째 자리까지 표현했다.

3) HAVING 절을 이용한 필터링 집계 함수(COUNT, SUM 등)의 결과를 조건으로 사용할 때는 WHERE 절이 아닌 HAVING 절을 사용해야 한다.

  • COUNT(DISTINCT order_id) >= 10: 하루 전체 주문 건수가 10건 이상인지 확인.
  • furniture_pct >= 40: 계산된 가구 비중이 40% 이상인지 확인.
    • 참고: 표준 SQL에서는 HAVING 절에 SELECT 절의 별칭(alias)인 furniture_pct를 직접 사용할 수 없고 수식을 그대로 다시 써야 한다. 하지만 MySQL 환경에서는 별칭 사용을 허용하므로 위 쿼리가 동작한다.

4) DISTINCT의 중요성 이커머스 데이터 특성상 한 주문에 여러 상품 행이 존재할 수 있다. 문제에서 요구하는 것은 '주문 수'이지 '판매 상품 수'가 아니므로, 반드시 DISTINCT order_id를 사용하여 중복된 주문 번호를 하나로 취급해야 한다.

이 문제는 분자와 분모를 각각 COUNT(DISTINCT ...)로 정확히 구해낼 수 있는지를 묻는, 데이터 분석 SQL에서 매우 빈출 되는 유형이다.