♟️ 알고리즘/Leetcode

[MySQL][Leet Code] 550. Game Play Analysis IV (Medium)

Jerry_K 2025. 3. 4. 17:24


https://leetcode.com/problems/game-play-analysis-iv/?envType=study-plan-v2&envId=top-sql-50


🗒️SQL 코드 풀이 

SELECT ROUND(COUNT(DISTINCT S.player_id) / COUNT(DISTINCT A.player_id ),2) AS fraction  
    FROM Activity A
    LEFT JOIN 
        (
            SELECT player_id, (MIN(event_date) + INTERVAL 1 DAY) AS seq_day
                FROM Activity
                GROUP BY player_id 
        ) S
    ON A.event_date = S.seq_day AND A.player_id = S.player_id

 

1. 겨우 하루 차이를 구하는 문제도 SQL로 하면 어려워진다.

 

2. "they first logged in" 라는 말이 있기 때문에, 첫날을 기준으로 연속 로그인 한 경우를 찾는다.

 

3. 연속 로그인이면 + 1 DAY의 값으로, 해당 컬럼을 생성하여 서브 쿼리를 만들어준다.

  • 각 아이디 별 첫날 로그인을 찾기위해, player_id 별 GROUP BY를 해줌
  • 그리고 MIN으로 첫날을 찾고 INTERVAL로 1 DAY를 더함

4. 이후 event_date와 +1 DAY 한 것 기준과 유저의 ID 기준으로 LEFT JOIN을 해준다.

 

5. 이후 DISTINCT로 중복을 제거하여 원하는 값을 계산해준다. 

 

나의 잘 못 된 풀이 1

SELECT  COUNT(DISTINCT Y.player_id) / COUNT(DISTINCT A.player_id)
FROM Activity A
LEFT JOIN 
(
    SELECT player_id, event_date, event_date - INTERVAL 1 DAY AS yesterday
        FROM Activity
) Y
ON  A.event_date = Y.yesterday AND A.player_id = Y.player_id 
GROUP BY A.player_id
  • GROUP BY로 하여 COUNT를 해도 그룹끼리 COUNT되는 문제 발생
    • GROUP BY를 했으니 그룹끼리만 계산... (멍청이)

 

나의 잘 못 된 풀이 2

SELECT ROUND(COUNT(DISTINCT Y.player_id) / COUNT(DISTINCT A.player_id),2) AS fraction 
FROM Activity A
LEFT JOIN 
(
    SELECT player_id, event_date, event_date - INTERVAL 1 DAY AS yesterday
        FROM Activity
) Y
ON  A.event_date = Y.yesterday AND A.player_id = Y.player_id
  • 이후 GROUP BY 제거 후, 위와 같이 하였는데 "they first logged in" 이 조건을 지키지 못함
  • 나의 코드는 첫날과는 무관하게 연속적이면 카운트

 

📌 문제 코멘트 

  • 날짜 데이터를 INTERVAL 1 DAY 로 연산하는 법을 몰랐음
  • GROUP BY 한 것을 SUM 이나 COUNT 하여 그룹끼리만 SUM,COUNT 됨
    • 어찌보면 당연한 말인데, 문제 풀 때는  전체가 COUNT 되지 않아서 이게 안되서 당황함

📚문제