👇 재구매가 일어난 상품과 회원 리스트 구하기
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
🔓 문제 설명
ONLINE_SALE 테이블에서 동일한 회원이 동일한 상품을 재구매한 데이터를 구하여, 재구매한 회원 ID와 재구매한 상품 ID를 출력하는 SQL문을 작성해주세요.
결과는 회원 ID를 기준으로 오름차순 정렬해주시고 회원 ID가 같다면 상품 ID를 기준으로 내림차순 정렬해주세요.
예시 문제 데이터(ONLINE_SALE)
| ONLINE_SALE_ID | USER_ID | PRODUCT_ID | SALES_AMOUNT | SALES_DATE |
| 1 | 1 | 3 | 2 | 2022-02-25 |
| 2 | 1 | 4 | 1 | 2022-03-01 |
| 4 | 2 | 4 | 2 | 2022-03-12 |
| 3 | 1 | 3 | 3 | 2022-03-31 |
| 5 | 3 | 5 | 1 | 2022-04-03 |
| 6 | 2 | 4 | 1 | 2022-04-06 |
| 2 | 1 | 4 | 2 | 2022-05-11 |
⚡SQL Query
SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) > 1
ORDER BY USER_ID ASC, PRODUCT_ID DESC;
🔎 풀이 설명
1. 그룹화: 회원ID와 상품ID를 그룹화하여 동일한 회원이 구매한 같은 상품 이력으로 묶었습니다.
2. 중복 조건: COUNT(*)를 사용하여 2회 이상(재구매) 데이터만 남겼습니다.
3. 정렬
💡인사이트
1. Hash Group By vs Sort Group By
- 인덱스가 없다면, 옵티마이저는 메모리에 해시 테이블을 만들어 그룹화하는 Hash Group By 방식을 사용
- [USER_ID + PRODUCT_ID] 인덱스가 있다면, 옵티마이저는 정렬된 데이터를 읽으며 Sort Group By 방식 사용
2. COUNT(*) vs COUNT(컬럼)
- 특정 조합의 존재 여부를 따질 때는 COUNT(*)가 성능상 유리합니다.
- COUNT(컬럼)은 NULL 여부까지 체크하므로 미세하지만 더 많은 연산이 필요할 수 있습니다.
3. 결합 인덱스 구성
- 위 쿼리에서 최적화된 인덱스는 [USER_ID + PRODUCT_ID] 순서 입니다.
- 쿼리에서 두 컬럼만 사용하고, 두 컬럼 모두 그룹화할 때 옵티마이저는 이미 정렬된 인덱스를 따라 읽어 별도의 Sort Group By나 Hash Group By 연산 없이 스캔만으로 그룹핑이 끝납니다.
'🗄️ DB_이야기 > # ⚡SQL' 카테고리의 다른 글
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 상위 n개 레코드(SELECT) (0) | 2026.04.15 |
|---|---|
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 오프라인/온라인 판매 데이터 통합하기(SELECT) (0) | 2026.04.14 |
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 서울에 위치한 식당 목록 출력하기(SELECT) (0) | 2026.04.13 |
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 강원도에 위치한 생산공장 목록 출력하기(SELECT) (0) | 2026.04.13 |
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 조건에 부합하는 중고거래 댓글 조회하기(SELECT) (0) | 2026.04.13 |