TIL 221001 개인프로젝트 SQL 쿼리
# 최솟값, 최댓값, 평균 구하기
count()와 같이, min(), max(), avg()로 사용한다.
Alias를 사용해서 별칭을 붙여줄 수 있다. ex) count(*) as cnt
# Group by, Order by
group by는 ' 중복을 제거하는 용도 '
쿼리가 실행되는 순서 : from → group by → select → order by
# 그룹, 오더를 where와 같이 쓰기
select payment_method, count(*) from orders
where email like '%naver.com' and course_title = '앱개발 종합반'
group by payment_method
like 까지 섞어쓰는 법이다.
# 어느것을 기준으로 order by를 할 것인가?
select '8월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at >= '2020-08-01'
group by c1.title, c2.week
order by c1.title DESC , c2.week
를 하면 c1.title 기준으로 내림차순이 되고,
select '8월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at >= '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week DESC
를 하면 c2.week 기준으로 내림차순이 된다.
# is NULL, is not NULL
select name, count(*) from users u
left join point_users pu on u.user_id = pu.user_id
where pu.point_user_id is NULL
group by name
-> NULL을 찾는 쿼리
select name, count(*) from users u
left join point_users pu on u.user_id = pu.user_id
where pu.point_user_id is not NULL
group by name
-> NULL을 걸러내는 쿼리
※ 주의! count 는 NULL을 세지 않는다.
# round
select count(point_user_id) as pnt_user_cnt,
count(*) as tot_user_cnt,
round(count(point_user_id)/count(*),2) as ratio
from users u
left join point_users pu on u.user_id = pu.user_id
where u.created_at between '2020-07-10' and '2020-07-20'
-> round로 감싸여진 값은 반올림을 수행한다.
round(count(point_user_id)/count(*),2) 는 소숫점 2번째 자리 까지 반올림하고 출력한다는 의미이며,
round(count(point_user_id)/count(*),0) 이 되면 당연히 소숫점 출력없이 반올림을 수행하고,
round(count(point_user_id)/count(*),1) 이 되면 소숫점 한 자리 까지 출력하고 반올림을 수행한다.
# Union All
select '7월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at < '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week
이렇게 7월이라고 명명한 결과값을
select '8월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at >= '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week
8월이라고 명명한 결과값과 합치고 싶다면?
(
select '7월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at < '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week
)
UNION ALL
(
select '8월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at >= '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week
)
이렇게 괄호로 각각의 쿼리를 묶어주고 UNION ALL을 써주면 된다.
다만 여기서 주의해야 할 점은, UNION ALL로 묶어주게 되면 order by가 깨지는 현상이 나타나는데,
order by를 동작하게 하려면 합친 뒤의 결과값에 정렬하는 쿼리를 넣어주여야 한다. 이에 대해서는
'서브쿼리'에 대한 학습이 필요하므로 다음에 다시 다루도록 하겠다.