오랑우탄의 반란

LeetCode 리트코드 | 1934. Confirmation Rate (MySQL) 본문

SQL/LeetCode

LeetCode 리트코드 | 1934. Confirmation Rate (MySQL)

5&2 2024. 7. 8. 20:42
반응형

 

오늘도 오랑이는 문제를 풉니다. 

 

1934. Confirmation Rate

 

조인을 활용해서 쉽게 풀 수 있는 문제입니다. 

SELECT s.user_id , round(ifnull(c2.confirm / c1.total,0),2)
         AS confirmation_rate
FROM signups s 
    left join (select user_id, count(*) as total from confirmations group by 1) c1 
    on s.user_id = c1.user_id
    left join (select user_id, count(*) as confirm from confirmations where action = 'confirmed' group by 1) c2 
    on s.user_id = c2.user_id ;

 

하지만 조금 장황한 감이 있어서 한줄코딩을 애정하는 오랑이는 해당 쿼리를 줄이고 싶습니다. 

JOIN 을 사용하는 대신, SELECT 에 다 넣어봅시다. 

action 이 confirmed 인 경우의 합을 전체 개수 count(*) 로 나눈 값에 대해서, null 인 경우 0 으로 치환되도록 합니다. 

SUM 안에 조건을 사용할 수 있더군요..

SELECT s.user_id , 
        round(ifnull(sum(action = 'confirmed')/count(*),0),2) AS confirmation_rate
FROM signups s left join confirmations c on s.user_id = c.user_id
GROUP BY 1 ;

 

다른 솔루션을 탐색하는 도중 엄청난 풀이를 발견했습니다. 

오랑이는 머리가 나빠서 이해하는 데 조금 걸렸지만 설명을 해보자면.. confirmed 인 케이스에 1, 나머지 케이스에 0을 부여해서 해당 값들에 대한 평균값이 결국 문제에서 요구하는 바(유저별 confirmed 케이스를 전체 케이스로 나눈 값)와 일치하기 때문에 avg 함수 사용이 스마트한 것이었습니다. 

group by 가 select 보다 먼저 실행된다는 점을 항상 염두해둬야 하는데 select에서 함수를 쓰다보면 매번 놓칩니다. 

select s.user_id, 
	round(avg(if(c.action="confirmed",1,0)),2) as confirmation_rate
from Signups as s left join Confirmations as c on s.user_id= c.user_id 
group by user_id;

 

 

오랑우탄이 영어를 하고 오랑이가 쿼리마스터가 되는 그날까지~

 

 

https://leetcode.com/problems/confirmation-rate/

 

반응형