-
12/13스파르타/TIL(Today I Learned) 2023. 12. 13. 14:45
1174. Immediate Food Delivery II
If the customer's preferred delivery date is the same as the order date, then the order is called immediate; otherwise, it is called scheduled.
The first order of a customer is the order with the earliest order date that the customer made. It is guaranteed that a customer has precisely one first order.
Write a solution to find the percentage of immediate orders in the first orders of all customers, rounded to 2 decimal places.이 문제를 보고 일단 영어라서 문제 이해가 안 되었다.
예시를 보아하니 order_date = customer_pref_delivery_date 가 조건이며
first_date 즉 min(order_date)를 구하는 문제였다.
나는 처음에 if문을 통하여 if(min(order_date)=customer_id_pref_delivery_date,' immediate',' scheduled')
로 해서 문제를 푸니 안 풀리고 문자열로 되어있어 어려웠다.
문자열을 1 , 0으로 해서 count를 해보는 등 여러 가지 방법을 시도했지만
실패하였다.
다른 답을 보니
where 절에 서브 쿼리를 넣어 customer_id와 order_date를 넣었다.
조건에 맞는 데이터 중 원하는 데이터를 뽑는 것이었는데
나의 실수는 서브 쿼리 없이 한 쿼리 안에서 해결하려는 것이었다.
select round(avg(order_date = customer_pref_delivery_date) *100,2) immediate_percentage from delivery where (customer_id,order_date) in ( select customer_id, min(order_date) as first_order from delivery group by customer_id )
https://leetcode.com/problems/immediate-food-delivery-ii/description
550. Game Play Analysis IV
이 문제를 보면 첫 로그인 이후 바로 다음날 접속한 사람의 비율을 구하고 싶어 한다.
따라서 datediff를 사용해서 문제를 풀었다.(해답과 함께)
여기서 처음 안 사실은 datediff에 over ( partition by가 가능하다는 것이다.)
이 문법을 사용하면 서브쿼리에서 group by로 묶을 필요도 없었다.
서브쿼리로 첫날 로그인( min(event_date))를 구하고 datediff로 첫날과 event_date 중 차이가 1 나는
즉 두 번째 날도 로그인 한 날짜를 구해서 login이라는 별칭(AS)을 붙였다.
select round(sum(a.login)/count(distinct a.player_id),2) fraction from ( select player_id ,datediff(event_date,min(event_date) over(partition by player_id)) = 1 AS login from activity ) a
DateDiff 에는 OVER( PARTITION BY )를 사용할 수 있다.
1141. User Activity for the Past 30 Days I
Write a solution to find the daily active user count for a period of 30 days ending 2019-07-27
inclusively. A user was active on someday if they made at least one activity on that day.이 문제를 푸는데 일단 문제가 이해가 안되었다.
대충 여러가지 찾아보니 2017-07-27 이전 30일 동안
활성화 한 사람이 있는지에 대한 문제였다.
datediff를 사용해도 되지만 date_sub이 특정 날짜에서 30일 이전을 구하기 쉽기 때문에
date_sub을 사용했다.
date_sub은 ("특정 날짜" , interval x(얼마만큼 뺄것인지) 날짜형식)으로 사용한다.
문제에서는 30일 전이라는 날짜를 구하기 때문에
date_sub (date("2019-07-27"), interval 30 day)로 사용했다.
2019-07-27을 문자열로 작성하고 date()를 통해 날짜 형식으로 바꿔주었다.
그렇게 구해진 날짜를 보면 2019-06-27이다 .
"우리가 구하고 싶은건 6월 27일 이후에 한번이라도 사용한 사람이 있는가?" 이다.
따라서 activity_date >= date_sub(~) 라는 조건이 주어진다.
여기서 보면 activity_date가 중복되어 있기 때문에
우리는 group by로 날짜를 묶어서 날짜 별로 활성화한 사람들을 볼것이다.
이때 where절을 사용해도 되지만, having절을 사용하여 더욱 코드를 간단하게 사용한다.
select activity_date as day ,count(distinct user_id) active_users from activity group by activity_date having activity_date> date_sub(date("2019-07-27"),interval 30 day) and activity_date < date("2019-07-29")
이 문제를 풀면서 깨달은 점
having절에는 if문을 쓸 수 없기 때문에
case when을 써야한다.