SQL

프로그래머스 SQL(11) - 재구매가 일어난 상품과 회원 리스트 구하기

김랑해 2023. 10. 29. 18:19

https://school.programmers.co.kr/learn/courses/30/lessons/131536

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

큰일났다 오랜만에 하니까 정말 하나도 기억이 안난다..

진짜 꾸준하게 했었어야 했는데

인턴생활한다고 바빠서.. 지금이라도 챙겨보려고 한다

 

엉엉.. 꾸역꾸역 하는중

 

오늘 해볼 고찰은.. GROUP BY

잘 와닿지 않지만 그냥 썼었는데 오늘 GROUP BY 에 대해서 좀 짚고 넘어가보려고 한다

 

 

일단 집계함수 COUNT

1. COUNT(*) 
- 조회된 전체 행수를 COUNT한다
2. COUNT(칼럼명) 
- 해당 칼럼의 NULL값을 제외하고 카운트한다

-  ex. age(13,15,21,null) -> 3 이 출력
3. COUNT(DISTINCT 칼럼명)
- 해당 칼럼의 종류를 COUNT해준다
- ex. food_type(한식,한식,중식,일식,일식,양식,양식,양식)
 # count(food_type) = 8
 # count(distinct food_type) = 4

 

COUNT(칼럼명) ~ GROUP BY 칼럼명

FOOD_TYPE끼리 그룹을 지어서 COUNT를 해준다는 의미

 

GROUP BY 칼럼명1, 칼럼명2

COUNT를 해주는데 먼저 대그룹으로 칼럼명 안을 나눈다(분식, 양식,일식...)

그 다음으로 대그룹 안에서 소그룹을 또 나눈다 (분식의 주차장 Y, N...)

 

 

역시 이런 건 무식하게 해보는 게 답이다

암튼 원래 문제로 돌아와서?

SELECT USER_ID, PRODUCT_ID
FROM (SELECT USER_ID, PRODUCT_ID, COUNT(USER_ID) COUNT
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID)
WHERE COUNT >= 2
ORDER BY USER_ID, PRODUCT_ID DESC

근데 생각해보면 COUNT(USER_ID)라고 안 하고 COUNT(*)으로 해도 됐었다

더 쉽게 풀 수 있는 방법이 없으려나..

HAVING절.. 내 기억상 WHERE절을 사용할 수 없는 곳에서 HAVING절을 사용한다고 기억하는데...

 

- 순서 : SELECT FROM WHERE GROUP BY HAVING ORDER BY
- 실제 실행 순서 : FROM -> CONNECT BY -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY
- WHERE절은 집계함수 사용 못함 ( COUNT, SUM, MIN, AVG...)

 

..  아하!

 

SELECT USER_ID, PRODUCT_ID, COUNT(USER_ID) COUNT
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT >= 2

일단 이건 안 된다. 왜냐하면 HAVING 절이 SELECT절보다 먼저 발생하기 때문에(HAVING할 때 COUNT라는 열이 존재하지 않음)

 

SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) > 1
ORDER BY USER_ID, PRODUCT_ID DESC

실행순서가 FROM > CONNECT BY > WHERE > GROUP BY > HAVING > SELECT > ORDER BY 라는 걸 명심하고

1. GROUP BY 로 USER_ID와 PRODUCT_ID를 묶고

2. HAVING COUNT(*)로 해당 열을 카운트 해서 1보다 많은 애들만 뽑는다

3. SELECT절을 통해서 USER_ID와 PRODUCT_ID만 추출하고

4. ORDER BY절을 통해 정렬한다

 

우와..일단 내가 몰랐던 건 HAVING COUNT(*)라는 거다

어쩌면 집계함수는 HAVING에서 사용할 수 있다는 말이 이런 말인가 보다

 

<LEARNING POINT>
1. COUNT와 GROUP BY의 관계 -> 위에 참조
2. 실행 순서를 꼭 기억하고 코드를 짤 것
FROM > CONNECT BY > WHERE > GROUP BY > HAVING > SELECT > ORDER BY
3. HAVING COUNT(*)