눈물의 똥꼬쇼를 펼친 문제. select-from-group 으로 끝낼 수 있는 문제를 cte, join, subquery까지 사용해가면서 풀었던 문제다. 간단하게 접근하는 연습이 필요할듯.
with user_number as(
select count(user_id) total_user -- user_name 이 아니라 user_id를 count해야한다. user_name이 없을 수도 있으니까?
from users
)
select
r.contest_id contest_id,
round(count(r.user_id)/(select total_user from user_number)*100, 2) percentage -- (등록 인원/전체 인원 수)*100
from Register r join Users u -- PK join
on u.user_id = r.user_id
group by contest_id
order by 2 desc, 1
이렇게 푼 이유는 다음과 같다.
select 절에서 전체 인원 수
를 구하겠다고 with절을 만들었다. 하지만
서브쿼리를 사용하여 SELECT 절에서 단일 값이나 계산된 값을 사용할 수 있다.
CTE 다 지우고 (select total_user from user_number)
을 select count(user_id) total_user
로 바꿔도 정답이다.
PK 보고 무지성 급발진 join을 했다. join 할 필요가 대체 어디 있냐..
select
r.contest_id,
round((count(r.user_id)/(select count(user_id) from Users))*100,2) as percentage
from Register r
group by r.contest_id
order by percentage desc, contest_id asc
count나 sum 같은 집계함수는 입력 인자 조건이 같아서 조건이 함수 안에 위치할 수 있다.
ex)
1. COUNT(CASE WHEN rating < 3 THEN 1 END)
rate가 3 미만인 값만 세고 싶을 때
2. SUM(CASE WHEN rating < 3 THEN 1 ELSE 0 END)
rate가 3 미만인 값만 세고 싶을 때(가중치 버전). " vip는 10, 나머지는 1값으로 하여 count해라" 같은 문제를 풀 때 유용하다.
select
query_name,
round(sum(rating / position) / count(query_name), 2) quality,
-- count(rating <= 3) / count(rating))
# round((CAST(SUM(CASE WHEN rating < 3 THEN 1 ELSE 0 END) AS DECIMAL) / COUNT(*) * 100), 2) AS poor_query_percentage
COUNT(CASE WHEN rating < 3 THEN 1 END) / COUNT(*) AS 비율
from queries
group by query_name
having quality is not null
select
query_name,
round(avg(rating/position),2) as quality,
round(sum(case when rating<3 then 1 else 0 end)*100/count(rating),2) as poor_query_percentage
from Queries
where query_name is not null
-- where 절에서 null값을 필터링 하는게 더 경제적이다.
group by query_name
칼럼의 null값을 배제하고 싶을 때는 where절에서 미리 필터링하는게 좋다.
95번에서 배운 방법으로 쉽게 풀었다.
기억하자.
집계함수는 인자()에 조건을 넣을 수 있다.
ex) 승인된 거래만 selec하고 싶은 경우
: sum(case when state = 'approved' then 1 else 0 end) from transactions
select
date_format(trans_date , "%Y-%m") month,
country,
count(id) trans_count,
sum(case when state = 'approved' then 1 else 0 end) approved_count ,
sum(amount) trans_total_amount,
sum(case when state = 'approved' then amount else 0 end) approved_total_amount
from transactions
group by month, country