안녕하세요! 데코입니다!
오늘은 프로그래머스 코딩테스트 연습에 있는 "재구매가 일어난 상품과 회원 리스트 구하기 문제를 포스팅하려고 합니다!
바로 포스팅 시작할게요! :)
(출처 : https://school.programmers.co.kr/learn/courses/30/lessons/131536)
1. 문제 : 재구매가 일어난 상품과 회원 리스트 구하기(Lv. 2)
2. 문제 설명
다음은 어느 의류 쇼핑몰의 온라인 상품 판매 정보를 담은 ONLINE_SALE 테이블입니다.
ONLINE_SALE 테이블은 아래와 같은 구조로 되어있며
ONLINE_SALE_ID, USER_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE는
각각 온라인 상품 판매 ID, 회원 ID, 상품 ID, 판매량, 판매일을 나타냅니다.
[ 테이블 구조 ]
COLUMN NAME | TYPE | NULLABLE |
ONLINE_SALE_ID | INTEGER | FALSE |
USER_ID | INTEGER | FALSE |
PRODUCT_ID | INTEGER | FALSE |
SALES_AMOUNT | INTEGER | FALSE |
SALES_DATE | DATE | FALSE |
동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.
[ 문제 ]
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 |
USER_ID 가 1인 유저가 PRODUCT_ID 가 3, 4인 상품들을 재구매하고,
USER_ID 가 2인 유저가 PRODUCT_ID 가 4인 상품을 재구매 하였으므로,
다음과 같이 결과가 나와야합니다.
[ 출력 결과 ]
USER_ID | PRODUCT_ID |
1 | 4 |
1 | 3 |
2 | 4 |
3. 문제 풀이
# 1안
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안 한 가지로 작성했습니다!
# 1안 풀이 설명
# [ 문제 접근 설명 ]
이번 문제의 요구사항을 정리해 보면,
동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재한다고 했고
재구매 이력이 있는 회원 ID와 상품 ID를 나타내는 문제입니다!
따라서 '회원 ID'와 '상품 ID'을 각각 의미하는 'USER_ID', 'PRODUCT_ID' 컬럼을 기준으로
'GROUP BY'문을 이용하여 집계하고
집계 결과에서 2회 이상 구매한 내역만 조회하면 되겠다고 생각했어요!
# [ 1안 쿼리 작성 설명 ]
ONLINE_SALE의 테이블에 존재하는 컬럼들이 [출력 결과]에 나와 있는 컬럼들과 동일하게
" SELECT "를 통해 " GROUP BY "문에 이용되는 컬럼을 선택
" GROUP BY {컬럼1}, {컬럼2} "를 이용해 'USER_ID', 'PRODUCT_ID' 컬럼별 집계 실행
" HAVING COUNT(*) > 1 "을 이용해 집계 결과에서 COUNT(*)가 2 이상인 데이터만을 조회
" ORDER BY {컬럼} ASC / DESC "를 통해
'USER_ID' 컬럼을 기준으로 오름차순 정렬, 'PRODUCT_ID' 컬럼을 기준으로 내림차순 정렬
이렇게 쿼리를 작성했습니다!
4. 데코의 문제 풀이 후기
이번 문제는 GROUP BY를 통해 집계하고, HAVING 문을 통해 집계 결과에 조건을 넣어 조회하는 문제예요!
제가 다룬 문제에서 처음으로 HAVING 문이 나왔네요!
SQL에서 HAVING 문은 집계 결과에 조건을 넣어 조건에 만족하는 결과를 조회할 때 사용합니다!
따라서 GROUP BY문 뒤에 사용을 해요!
HAVING 문에서는 이전 포스팅에서 다룬 집계함수를 통해 조건을 추가할 수 있어요!
- MAX : 컬럼의 최댓값을 산출
- MIN : 컬럼의 최소값을 산출
- SUM : 컬럼의 값을 합계를 산출
- COUNT : 컬럼의 갯수를 산출
- AVG : 컬럼의 평균값을 산출
WHERE 문에서도 조건을 통해 필터링을 하고
HAVING 문에서도 조건을 통해 필터링한다고 해서 혼동하시는 분이 있을 수도 있을 것 같아요!
WHERE 문과 HAVING 문은 분명한 차이점이 있어요!
WHERE 문에서는 데이터에서 ROW(행)에서 조건을 만족하는 데이터만을 필터링하는 구문이고!
HAVING 문은 GROUP BY문을 통해 집계한 이후 만족하는 데이터만을 필터링하는 구문이에요!
아래에 간단한 예시를 들어볼게요!
[ WHERE 문 : ROW(행)에서 조건을 적용 ]
# DB라는 테이블에서 PRICE가 500을 초과하는 데이터를 조회
# WHRE 문
SELECT USER_ID
, PRICE
FROM DB
WHERE PRICE > 500
[ HAVING 문 : GROUP BY 문을 통해 집계한 결과에서 조건을 적용 ]
# DB라는 테이블에서 USER_ID의 데이터 수를 집계하고 1개를 초과하는 데이터를 조회
# HAVING 문
SELECT USER_ID
, COUNT(*)
FROM DB
GROUP
BY USER_ID
HAVING COUNT(*) > 1
HAVING 문 그리고 WHERE 문과의 차이점에 대하여 이해가 가셨나요?
집계해서 데이터를 조회할 때, 집계 결과 모두를 봐도 되지만
오늘 다룬 문제처럼 "재구매한 고객"에 관심을 가지고 조회하고 싶을 수 있습니다!
이때 집계 결과에서 HAVING 문을 통해 조건을 통해 특정한 값만을 확인할 수 있습니다!
이번 문제는 GROUP BY를 통해 집계하고, HAVING 문을 통해 집계 결과에 조건을 넣어 조회하는 문제를 풀어봤습니다!
설명이 어려운 부분 혹은 잘 이해가 안 가는 부분은 그리고 더 궁금한 내용이 있다면
언제든지 댓글로 남겨주세요!
빠르게 궁금증을 해결해드릴게요!
공감과 댓글은 큰 힘이 됩니다!
읽어주셔서 감사해요!
또 다른 SQL 문제로 찾아뵐게요!
'Skill Sets > SQL' 카테고리의 다른 글
[SQL] 자동차 종류 별 특정 옵션이 포함된 자동차 수 구하기(프로그래머스/MySQL/Level 2) (30) | 2023.01.16 |
---|---|
[SQL] 평균 일일 대여 요금 구하기(프로그래머스/MySQL/Level 1) (45) | 2023.01.14 |
[SQL] 가격대 별 상품 개수 구하기(프로그래머스/MySQL/Level 2) (33) | 2023.01.10 |
[SQL] 카테고리 별 상품 개수 구하기(프로그래머스/MySQL/Level 2) (25) | 2023.01.08 |
[SQL] 중복 제거하기(프로그래머스/MySQL/Level 2) (16) | 2023.01.04 |