오랑우탄의 반란
LeetCode 리트코드 | 550. Game Play Analysis IV (MySQL) DATE_ADD/DATE_SUB 시간과 날짜 계산 본문
LeetCode 리트코드 | 550. Game Play Analysis IV (MySQL) DATE_ADD/DATE_SUB 시간과 날짜 계산
5&2 2024. 7. 11. 15:15
오늘도 오랑이는 문제를 풉니다.
550. Game Play Analysis IV
풀이 과정
우선 날짜 조건을 지정해줍니다.
이전에 봤던 SELF JOIN 을 활용한 문제와 비슷하게 DATEDIFF(날짜1, 날짜2) = 1 AND 날짜2 > 날짜1 조건으로 풀려고 했는데 이보다 더 간단한 시간/날짜 계산 함수가 있었습니다.
DATE_ADD & DATE_SUB 시간/날짜 계산 함수
사용 방법은 간단합니다. 기준 날짜와 계산 단위를 인수로 받아서 작동합니다.
DATE_ADD
DATE_ADD(기준날짜, INTERVAL 기간)
#예시
DATE_ADD(NOW(), INTERVAL 3 DAY)
--> 현재 날짜 + 3일
DATE_SUB
DATE_SUB(기준날짜, INTERVAL 기간)
#예시
DATE_SUB(NOW(), INTERVAL 3 DAY)
--> 현재 날짜 - 3일
해당 함수를 활용해 조건을 짜면 아래와 같습니다.
event_date 를 기준으로 하루 뺀 날, 즉 연속된 두 날짜 중 먼저 오는 날짜가 기존 event_date 열에 있는 경우를 추출해줍니다.
where (player_id, date_sub(event_date, interval 1 day))
in (select player_id, event_date from activity group by player_id)
이에 대해 select 문에서 개수를 세어서 나눠줍니다.
select count(player_id) / (select count(distinct player_id) from activity)
from activity
where (player_id, date_sub(event_date, interval 1 day))
in (select player_id, event_date from activity group by player_id)
그리고 round까지 해주면 완성입니다.
최종 코드
select round(count(player_id) / (select count(distinct player_id) from activity),2) as fraction
from activity
where (player_id, date_sub(event_date, interval 1 day))
in (select player_id, min(event_date) from activity group by player_id) ;
where ~ in 서브쿼리는 쿼리의 효율성을 떨어뜨리기 때문에 좀 더 효율적은 쿼리로 업데이트 된 풀이방식입니다.
activity 테이블을 셀프조인 해주되, join 서브쿼리로 각 사용자의 최초 로그인 일자 (a2.event_date)를 구해주며,
join 조건으로 player_id 와 함께 최초 로그인 일자 +1일이 되도록 넣어줍니다.
그렇게 되면 최종 조인된 테이블을 연속으로 로그인한 distinct 유저만 남게 되고,
select 문에서 해당 유저를 카운트한 것을 전체 서브쿼리 카운트로 나눠줍니다.
SELECT ROUND(COUNT(A1.PLAYER_ID)/(SELECT COUNT(DISTINCT PLAYER_ID) FROM ACTIVITY),2) AS FRACTION
FROM ACTIVITY A1
JOIN (SELECT PLAYER_ID, MIN(EVENT_DATE) AS EVENT_DATE
FROM ACTIVITY
GROUP BY PLAYER_ID) A2
ON A1.PLAYER_ID=A2.PLAYER_ID
AND A1.EVENT_DATE = DATE_ADD(A2.EVENT_DATE, INTERVAL 1 DAY) ;
오랑우탄이 영어를 하고 오랑이가 쿼리마스터가 되는 그날까지~
https://leetcode.com/problems/game-play-analysis-iv/description/
'SQL > LeetCode' 카테고리의 다른 글
LeetCode 리트코드 | 180. Consecutive Numbers (MySQL) LAG, LEAD (0) | 2024.07.19 |
---|---|
LeetCode 리트코드 | 1045. Customers Who Bought All Products (MySQL) (0) | 2024.07.15 |
LeetCode 리트코드 | 1174. Immediate Food Delivery II (MySQL) (0) | 2024.07.11 |
LeetCode 리트코드 | 1193. Monthly Transactions I (MySQL) (0) | 2024.07.11 |
LeetCode 리트코드 | 1251. Average Selling Price (MySQL) (0) | 2024.07.09 |