본문 바로가기

[공부] SQL

[SQL 코딩테스트] 리트코드 Sorting and Grouping 정답

어쩌다 보니 '해야 하는' 일들 중 코딩테스트가 제일 재밌는 일(?)이 되어 버려서 자꾸 여기로 도망온다.

오늘은 아침 일과 시작으로 코테부터 빠르게 뿌수고 진짜 해야 하는 일을 하러 가련다.

 


2356. Number of Unique Subjects Taught by Each Teacher
#DISTINCT #GROUPBY
⏰ 4:47
SELECT TEACHER_ID, COUNT(DISTINCT SUBJECT_ID) CNT
FROM TEACHER
GROUP BY TEACHER_ID

 

1141. User Activity for the Past 30 Days I
#BETWEEN #GROUPBY
⏰ 11:07

 

비트윈 함수를 쓸 때 무조건 AND 앞에 작은 숫자, 뒤에 큰 숫자가 와야 하는지 처음 알았다... 순서만 바꾸면 되는 거였는데 덕분에 또 한참 헤멤.

+ 날짜 문제에서 30일을 구하라고 하면 하루 빼줘야 하는거 매번 헷갈린다... ^_ㅠ

SELECT ACTIVITY_DATE AS DAY, COUNT(DISTINCT USER_ID) AS ACTIVE_USERS
FROM ACTIVITY
WHERE ACTIVITY_DATE BETWEEN '2019-07-27' - INTERVAL 29 DAY AND '2019-07-27'
GROUP BY ACTIVITY_DATE

 

 

[MEDIUM] 1070. Product Sales Analysis III
WHERE / IN / JOIN
⏰ 3:22
SELECT S.PRODUCT_ID, YEAR AS FIRST_YEAR, QUANTITY, PRICE
FROM SALES S
     JOIN PRODUCT P
     USING (PRODUCT_ID)
WHERE (PRODUCT_ID, YEAR) IN (
        SELECT PRODUCT_ID, MIN(YEAR)
        FROM SALES
        GROUP BY PRODUCT_ID
)

 

596. Classes More Than 5 Students
#GROUPBY #HAVING
⏰ 1:25

 

이런 문제는 이제 눈 감고도 푼다(?) 신난다!!!

SELECT CLASS
FROM COURSES
GROUP BY CLASS
HAVING COUNT(STUDENT) >= 5

 

1729. Find Followers Count
#GROUPBY #COUNT
⏰ 1:26
SELECT USER_ID, COUNT(FOLLOWER_ID) AS FOLLOWERS_COUNT
FROM FOLLOWERS
GROUP BY USER_ID
ORDER BY USER_ID

 

619. Biggest Single Number
#SUBQUARY #MAX
⏰ 10:19

 

아무리 봐도 맞는데 왜 틀렸다구루지...?🥺🥺🥺

그냥 LIMIT을 쓰면 안 되는 문제인건지, IFNULL에 NULL이 출력되면 안 되는 법이라도 있는건지...?

 

혹시 틀린 이유를 아시는 분 댓글 부탁드립니다 🙌🙌

SELECT IFNULL(NUM,'null') AS num
FROM MYNUMBERS
GROUP BY NUM
HAVING COUNT(NUM) = 1
ORDER BY NUM DESC
LIMIT 1

 

> 추측 : 예를 들면 다른 열에는 값이 있지만 NUM 열에 기록된 값이 없을 때, NULL을 뽑아주는 건데 아예 행 자체에 값이 없으니 NULL조차 뽑아주지 않음.

 

* 다시 궁금해진 것 : 아래와 같이 뽑으면 값이 그냥 비어서 나오고, [정답]과 같이 뽑으면 NULL이 출력된다. 차이가 뭘까?

SELECT MAX(NUM) AS num
FROM MYNUMBERS
GROUP BY NUM
HAVING COUNT(NUM) = 1
ORDER BY NUM DESC
LIMIT 1

 

[정답] 서브쿼리와 MAX 활용하기

SELECT MAX(num) AS num
FROM (
SELECT num
FROM MyNumbers
GROUP BY num
HAVING COUNT(num) = 1
) as unique_number
;

 

[MEDIUM] 1045. Customers Who Bought All Products
WITH / GROUP_CONCAT / HAVING
⏰  24:14

 

[정답 1] WITH 구문으로 문제 세상에서 제일 어렵게 풀기 ^^

WITH C_GROUP AS (
    SELECT CUSTOMER_ID, GROUP_CONCAT(DISTINCT PRODUCT_KEY ORDER BY PRODUCT_KEY) AS C_GROUP_KEY
FROM CUSTOMER
GROUP BY CUSTOMER_ID
ORDER BY CUSTOMER_ID
),

P_GROUP AS (
    SELECT GROUP_CONCAT(DISTINCT PRODUCT_KEY ORDER BY PRODUCT_KEY) AS P_GROUP_KEY
    FROM PRODUCT
)

SELECT CUSTOMER_ID
FROM C_GROUP C, P_GROUP P
WHERE C_GROUP_KEY = P_GROUP_KEY

 

[정답 2] GROUP BY / HAVING / 서브쿼리 사용하기

SELECT CUSTOMER_ID
FROM CUSTOMER
GROUP BY CUSTOMER_ID
HAVING COUNT(DISTINCT PRODUCT_KEY) = (SELECT COUNT(*) FROM PRODUCT)

 


이제 알았다... 코드와 함수의 복잡다양한 활용법들을 다 안다고 해도 소용 없다.

코드를 뽑기 전에 문제만 보고 어떻게 풀 수 있을지 머릿속에서 논리구조를 쉽고 짧게 잘 짜는 사람이 승자다...

이래서 데이터 분석을 할 때 데이터를 보기 전에 문제 정의와 가설 설정을 먼저 하라고 하는구나. 이것도 많이 하다 보면 경험치가 쌓이겠지. 화이팅!