📌 문제
문제 설명
다음은 어느 의류 쇼핑몰의 온라인 상품 판매 정보를 담은 ONLINE_SALE 테이블 입니다. ONLINE_SALE 테이블은 아래와 같은 구조로 되어있으며 ONLINE_SALE_ID, USER_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE는 각각 온라인 상품 판매 ID, 회원 ID, 상품 ID, 판매량, 판매일을 나타냅니다.
동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.
문제
ONLINE_SALE 테이블에서 동일한 회원이 동일한 상품을 재구매한 데이터를 구하여, 재구매한 회원 ID와 재구매한 상품 ID를 출력하는 SQL문을 작성해주세요. 결과는 회원 ID를 기준으로 오름차순 정렬해주시고 회원 ID가 같다면 상품 ID를 기준으로 내림차순 정렬해주세요.
📌 나의 풀이
Code
SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(PRODUCT_ID) > 1
ORDER BY USER_ID ASC, PRODUCT_ID DESC;
Solution
1. USER_ID, PRODUCT_ID 기준으로 그룹화
- 같은 사용자(USER_ID)가 동일한 상품(PRODUCT_ID)을 구매한 기록들을 하나의 그룹으로 묶는다는 뜻
2. 그룹화된 상태에서 HAVING을 이용하여 각 그룹 내 PRODUCT_ID가 1보다 큰 그룹만 선택
- COUNT(PRODUCT_ID) 사용
3. USER_ID를 기준으로 오름차순 정렬, PRODUCT_ID 기준으로 내림차순 정렬
4. USER_ID, PRODUCT_ID만 출력
📌 다른 사람의 풀이
Code
SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) > 1
ORDER BY USER_ID, PRODUCT_ID DESC;
Solution
1. USER_ID, PRODUCT_ID 기준으로 그룹화
- 같은 사용자(USER_ID)가 동일한 상품(PRODUCT_ID)을 구매한 기록들을 하나의 그룹으로 묶는다는 뜻
2. 그룹화된 상태에서 HAVING을 이용하여 각 그룹에 속하는 행 개수가 1보다 큰 행만 가져오기
- COUNT(*) 사용
3. USER_ID를 기준으로 오름차순 정렬, PRODUCT_ID 기준으로 내림차순 정렬
- ASC는 default이므로 위 코드에서는 생략되었음
4. USER_ID, PRODUCT_ID만 출력
배운 내용
1. COUNT(*)가 가능할 때에는 이왕이면 COUNT(*)를 사용해보자
저는 COUNT(PRODUCT_ID)라고 쿼리를 작성했지만, 개인적으로 COUNT(*)가 더 좋은 쿼리인 것 같습니다.
이유는 아래와 같습니다.
1. 가독성
이 문제의 경우, GROUP BY에 의해 이미 그룹화된 결과를 다루고 있습니다.
즉, NULL이 없다는 것이고, 그 상황에서는 그룹 내 전체 행 수를 반환하는 COUNT(*)를 사용하는 것이 더 명확하고 직관적이었을 것 같습니다.
2. 성능
COUNT(*)를 사용하면, SQL 엔진이 PRODUCT_ID 컬럼을 따로 검사할 필요 없이 모든 행을 세게 되므로 코드가 더 효율적으로 동작할 수 있습니다.
2. ORDER BY에서 ASC는 default 값이므로 생략될 수 있다.
다른 사람의 코드를 봤을 때, 저는 ASC가 없는 것을 보고 가장 뒤에 있는 DESC가 모두 적용되는 줄 알았습니다.
그러나 알고보니 ASC는 ORDER BY의 default 설정이여서 생략될 수 있었습니다.
가독성 있는 쿼리는 아니지만, 다른 사람의 쿼리도 잘 이해할 수 있어야하기 때문에 default가 뭔지 잘 알아둬야겠습니다.
'Coding Test > Programmers' 카테고리의 다른 글
[Programmers / MySQL] 특정 형질을 가지는 대장균 찾기 (Level 1) (0) | 2024.09.10 |
---|---|
[Programmers / MySQL] 오프라인/온라인 판매 데이터 통합하기 (Level 4) (0) | 2024.09.03 |
[Programmers / MySQL] 12세 이하인 여자 환자 목록 출력하기 (Level 1) (0) | 2024.09.02 |
[Programmers / MySQL] 서울에 위치한 식당 목록 출력하기 (Level 4) (0) | 2024.09.02 |