문제 사이트
https://school.programmers.co.kr/learn/courses/30/lessons/131536
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제
ONLINE_SALE 테이블에서 동일한 회원이 동일한 상품을 재구매한 데이터를 구하여, 재구매한 회원 ID와 재구매한 상품 ID를 출력하는 SQL문을 작성해주세요. 결과는 회원 ID를 기준으로 오름차순 정렬해주시고, 회원 ID가 같다면 상품 ID를 기준으로 내림차순 정렬해주세요.
ONLINE_SALE 테이블은 온라인 상품 판매 ID, 회원 ID, 상품 ID, 판매량, 판매일을 나타냅니다.
풀이
이번 문제는 동일한 회원(USER_ID)이 동일한 상품(PRODUCT_ID)을 두 번 이상 구매했는지를 확인하는 문제입니다.
이를 해결하기 위해 그룹화(GROUP BY)와 조건 필터링(HAVING)을 활용하였습니다.
1. 그룹화(GROUP BY)
GROUP BY는 특정 컬럼을 기준으로 데이터를 그룹화하는 데 사용합니다. 이 문제에서는 USER_ID와 PRODUCT_ID를 기준으로 그룹화하여 "동일한 회원이 동일한 상품을 얼마나 구매했는지"를 확인합니다.
(이렇게 하면 각 USER_ID와 PRODUCT_ID 조합별로 하나의 그룹이 생성)
GROUP BY USER_ID, PRODUCT_ID
2. 조건 필터링(HAVING)
HAVING 절은 GROUP BY로 그룹화된 결과에서 특정 조건을 만족하는 그룹만 필터링할 때 사용합니다.
이번 문제에서는 구매 횟수가 2회 이상인 데이터를 필터링하기 위해 사용합니다.
여기서 COUNT(*)는 각 그룹에 해당하는 레코드 수, 즉 동일한 상품의 구매 횟수를 의미합니다.
따라서 2회 이상 구매한 데이터를 추출할 수 있습니다.
HAVING COUNT(*) >= 2
3. 결과 정렬하기(ORDER BY)
마지막으로 결과를 정렬하여 회원 ID(USER_ID)는 오름차순, 동일한 회원 ID일 경우 상품 ID(PRODUCT_ID)는 내림차순으로 정렬합니다.
- ASC: 오름차순 정렬
- DESC: 내림차순 정렬
ORDER BY USER_ID ASC, PRODUCT_ID DESC
최종 SQL 코드
SELECT
USER_ID,
PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) >= 2
ORDER BY USER_ID ASC, PRODUCT_ID DESC;
출력 결과 예시

다른 사람의 풀이
생각보다 다양한 방법이 있었는데
그 중 하나로 자기 자신과 JOIN하여 판매일을 기준으로 이전 구매가 있는지 확인하는 방식도 가능합니다.
이 방법은 테이블을 자기 자신과 JOIN하여 구매일을 직접 비교하여 재구매 여부를 판단하는 방식입니다.
SELECT DISTINCT
os1.USER_ID,
os1.PRODUCT_ID
FROM ONLINE_SALE os1
JOIN ONLINE_SALE os2
ON os1.USER_ID = os2.USER_ID
WHERE os1.PRODUCT_ID = os2.PRODUCT_ID
AND os1.SALES_DATE < os2.SALES_DATE
ORDER BY os1.USER_ID ASC, os1.PRODUCT_ID DESC;
쿼리 설명
- FROM ONLINE_SALE os1 JOIN ONLINE_SALE os2 ON os1.USER_ID = os2.USER_ID
이 부분은 같은 유저의 구매 내역끼리 서로 비교하기 위해 ONLINE_SALE 테이블을 자기 자신과 조인 - WHERE os1.PRODUCT_ID = os2.PRODUCT_ID
같은 상품을 구매한 경우만 비교 대상이 됩니다. - AND os1.SALES_DATE < os2.SALES_DATE
os1이 os2보다 먼저 구매한 경우만 필터링
즉, 시간 순서상 앞선 구매가 있을 때만 재구매로 인정하게 되고
반대로 os1의 날짜가 더 늦은 경우(예: 나중 구매 → 과거 구매)는 의미가 없으며 제외됩니다. - SELECT DISTINCT
같은 유저와 상품 조합이 여러 번 재구매된 경우 중복을 제거하고 한 번만 출력하기 위해 사용합니다. - ORDER BY USER_ID ASC, PRODUCT_ID DESC
결과는 회원 ID 오름차순, 같은 회원일 경우 상품 ID 내림차순으로 정렬!!
'프로그램및 언어 > SQL' 카테고리의 다른 글
[SQL 코테] 모든 레코드 조회하기 (0) | 2025.04.11 |
---|---|
[SQL 코테] 3월에 태어난 여성 회원 목록 출력하기 (1) | 2025.04.03 |
[SQL 코테] 조건에 부합하는 중고거래 댓글 조회하기 (0) | 2025.04.02 |
[SQL 코테] 조건에 맞는 도서 리스트 출력하기 (0) | 2025.03.31 |
[SQL 코테] 12세 이하인 여자 환자 목록 출력하기 (0) | 2025.03.30 |