TIL

TIL 221001 개인프로젝트 SQL 쿼리

Vince_rf 2022. 10. 1. 18:31

# 최솟값, 최댓값, 평균 구하기

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를 동작하게 하려면 합친 뒤의 결과값에 정렬하는 쿼리를 넣어주여야 한다. 이에 대해서는

'서브쿼리'에 대한 학습이 필요하므로 다음에 다시 다루도록 하겠다.