SQL 코드카타
if/case when 조건문 활용
문제 95. 1633. Percentage of Users Attended a Contest
We define query quality as:
The average of the ratio between query rating and its position.
We also define poor query percentage as:
The percentage of all queries with rating less than 3.
Write a solution to find each query_name, the quality and poor_query_percentage.
Both quality and poor_query_percentage should be rounded to 2 decimal places.
Return the result table in any order.
The result format is in the following example.
select query_name,
round(avg(rating/position), 2) as quality,
round((select count(*) from queries where query_name = q1.query_name and rating <3)/count(*)*100, 2) as poor_query_percentage
from queries q1
where query_name is not null
group by 1
크게 어렵진 않았는데 효율성이 떨어져서 다른 답들을 보니
select query_name,
round(avg(rating/position), 2) as quality,
round(sum(if(rating < 3, 1, 0))/count(*)*100, 2) as poor_query_percentage
from queries
where query_name is not null
group by 1
SELECT
query_name,
ROUND(AVG(rating/position), 2) AS quality,
ROUND(SUM(CASE WHEN rating < 3 THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS poor_query_percentage
FROM
Queries
WHERE query_name is not null
GROUP BY
query_name;
if나 case when을 사용해서 훨씬 더 간단하게 쿼리를 작성할 수 있었음(둘 다 빠른데 왜인지 case when이 더 효율적이라고 나옴)!
서브쿼리 없이 작성할 수 있다는 것은 둘째 치고, 문제가 해당하는 케이스를 count 해주는 문제인데 조건문을 활용했다는 것이 신기했다. 앞으로 자주 쓰게 되는 방법이지 않을까?
일단 덕분에 아래 문제도 금방 쉽게 풀 수 있었음
문제96. 1193. Monthly Transactions I
select date_format(trans_date, '%Y-%m') as month,
country,
count(*) as trans_count,
sum(if(state = "approved", 1, 0)) as approved_count,
sum(amount) as trans_total_amount,
sum(if(state = "approved", amount, 0)) as approved_total_amount
from transactions
group by 1, 2;
case를 count하는 문제의 경우, 조건문을 사용해서 1과 0으로 치환해서 sum해줄 것!
count라고 반드시 count 함수를 써줘야하는 것은 아니다!
문제97. 1174. Immediate Food Delivery II
select sum(if(min(order_date) = min(customer_pref_delivery_date), 1, 0)) as immediate_percentage
from delivery
group by customer_id
그룹 함수의 잘못된 사용이라면서 오류남;;;
select round(sum(ip)/count(*)*100, 2) as immediate_percentage
from (select if(min(order_date) = min(customer_pref_delivery_date), 1, 0) ip
from delivery
group by customer_id) a
일단 답은 맞았지만 영 찜찜한 답. 만약 리스트에서 order_date의 최저값과 customer_pref_delivery_date의 행이 일치하지 않는 예제가 나왔더라면 실패했을듯.
Select
round(avg(order_date = customer_pref_delivery_date)*100, 2) as immediate_percentage
from Delivery
where (customer_id, order_date) in (
Select customer_id, min(order_date)
from Delivery
group by customer_id
);
다른 사람의 답안인데 내일 다시 해봐야할 듯 하다.
TMI
-잠을 요 며칠 제대로 못 잤더니 집중력/컨디션 최악의 날 중 하나였던듯;
-전까진 다른 사람들 답변을 크게 신경 안 쓰고 답만 맞으면 그만이다라는 생각이었는데, 공부를 하면 할 수록 다른 사람들의 답을 더 신경쓰게 되는 것 같다. 열심히 풀어서 장황하게 작성했는데 훨씬 깔끔한 쿼리를 보면 승부욕이 타오른달까. 더더 공부를 열심히 해야겠다.
'TIL 통합' 카테고리의 다른 글
01/12 기초 프로젝트 2일차 (0) | 2024.01.12 |
---|---|
01/11 프로젝트 시작 (0) | 2024.01.11 |
01/09 reverse(), reversed(), Counter() (0) | 2024.01.09 |
01/08 TIL (0) | 2024.01.08 |
01/05 개인과제 문제 풀이 과정 (0) | 2024.01.05 |