문제
ONLINE_SALE 테이블에서 동일한 회원이 동일한 상품을 재구매한 데이터를 구하여, 재구매한 회원 ID와 재구매한 상품 ID를 출력하는 SQL문을 작성해주세요. 결과는 회원 ID를 기준으로 오름차순 정렬해주시고 회원 ID가 같다면 상품 ID를 기준으로 내림차순 정렬해주세요.
[요약]
동일 회원이 동일 상품을 재구매한 데이터를 회원ID와 상품ID를 컬럼으로 지정하여 출력(단, 정렬 1순위-회원ID, 2순위-상품ID
정답
SELECT USER_ID, PRODUCT_ID -- 조건의 유저와 상품 ID를 컬럼으로 지정
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID -- 동일한 유저가 동일한 상품을 구매한 것을 출력해야 하니, 유저-상품을 그룹핑
HAVING COUNT(*) > 1 -- 그룹핑된 유저-상품의 카운트가 1보다 크면 중복 구매가 일어난 것
ORDER BY USER_ID, PRODUCT_ID DESC; -- 정렬 1순위: 유저ID / 2순위: 상품ID
이 문제를 보고, GROUP BY를 떠올리지 못한 사람들은 USER_ID와 PRODUCT_ID를 왜 그룹핑하는지 이해가 안 될 수도 있을 것이다.
책을 보고 배웠다면, GROUP BY는 집계 합수를 사용해야 할 때 사용한다고 들었는데 어째서 집계할 필요가 없는데 그룹핑하는 걸까?
라는 생각이 들 수 있다.
하지만, 컬럼에 집계가 안 들어가는 것이지, 중복되는 값을 출력하기 위해서는 동일한 레이블이 2개 이상이어야 한다.
바로 이 부분!
에서 집계가 사용되는 것이다.
문제에서 "동일한 회원이 동일한 상품을 재구매한 데이터"를 구한다는 워딩에서, 우리는 한 회원이 한 상품을 구매한 레이블이 2개 이상 되어야 '재구매'가 일어난 것이라는 점을 파악해야 한다.
예시
유저 | 상품 |
A | 무스탕 |
A | 무스탕 |
이해가 안 되는 분들을 위해 위의 표를 예로 들자면, 'A'회원이 '무스탕'이라는 상품을 재구매했다는 사실을 알려면, 해당 표와 같이 유저-상품으로 그룹핑된 레이블이 2개 이상 있어야 한다는 것이다.
이를 파악했다면
`GROUP BY USER_ID, PRODUCT_ID` 라는 코드를 작성할 수 있을 것이고,
`HAVING COUNT(*) > 1` 와 같이 그룹핑된 레이블을 카운트한 개수가 2개 이상이어야 한다는 아래의 코드를 작성할 것이다.
GROUP BY와 HAVING에 대해 잘 모르는 분들은 이 글 또한 이해가 되지 않을 수 있다.
그런 분들의 아래의 블로그를 참고해주시기 바란다.
https://jsum01.tistory.com/entry/GROUP-BY%EC%99%80-HAVING
'데이터베이스_Database > SQL' 카테고리의 다른 글
[SQL] Constraint, 제약조건 (0) | 2024.04.13 |
---|---|
[SQL]MySQL Oracle_SQL의 날짜 포맷 (2) | 2023.12.03 |
[Oracle SQL][프로그래머스_131537] 오프라인/온라인 판매 데이터 통합하기 (0) | 2023.12.03 |
[SQL]UNION, UNION ALL 차이 (0) | 2023.12.03 |
[SQL]GROUP BY와 HAVING? (0) | 2023.11.23 |