[ 웹개발, 앱개발 종합반의 week 별 체크인 수를 세어보기 & 보기 좋게 정리해보기 ]
select c.title, ch.week, count(*) as cnt from courses c
inner join checkins ch on c.course_id = ch.course_id
group by ch.week, c.title
order by ch.week, c.title
- Group by 는 한가지 필드를 대상으로만 할 수 있는 줄 알았는데, 생각지도 못하게 두 개 이상의 필드로 할 수 있는 것을 알고 놀랐다.
< Group by {field1}, {field2} >
- Group by {field1}
-> 이 때, {field 1}의 값들로 구분되어 모여진 데이터를 모아놨다가 ( a )
Group by {field1}, {field2}
이렇게 되면, ( a ) 데이터 덩어리를 다시, {field2}를 기준으로 다시 나눠서 모아준다.
Order by 도 마찬가지로 동작한다.
-- 위 문제에서, 8월 1일 이후에 구매한 고객들만 발라내기
select c.title, ch.week, count(*) as cnt from courses c
inner join checkins ch on c.course_id = ch.course_id
inner join orders o on ch.user_id = o.user_id
where o.created_at >= '2020-08-01'
group by c.title, ch.week
order by c.title, ch.week
SQL은 같은 데이터 셋 결과가 나올 수 있는 방법이 여러가지다!
모로가도, 데이터만 나오면 된다 ! ( 쿼리 최적화는 나중에 생각하자 ! )
https://developer-talk.tistory.com/420
[SQL]간단하면서 쉬운 쿼리 최적화 방법
쿼리 최적화는 상당히 어려우며 복잡합니다. 최적화되지 않은 쿼리는 CPU, 메모리를 불필요하게 소모하고 서비스를 사용하는 사용자에게 불편함을 제공합니다. 하지만 초급 개발자가 쿼리를 최
developer-talk.tistory.com
[ Inner Join vs Left Join ]
Left Join에서 A테이블에서 B테이블을 합쳐주는 것인데,
이 때 B테이블의 필드값들이 NULL이더라도, 포함시켜 표현해준다.
[ 등록한 유저 중, 아직 강의를 시작하지 않은 = 포인트가 없는 유저를 성씨별로 나타내주는 쿼리 ]
즉 point_users 테이블의 필드값들이 존재하지 않는 = point_user_id가 존재하지 않는!
select u.name, count(*) as cnt from users u
left join point_users pu on u.user_id = pu.user_id
where pu.point_user_id is NULL
group by u.name
order by cnt desc
Left Join은, 조인 시키는 테이블의 필드값이 없는 경우의 데이터들을 이용해 작업을 할 때 쓰인다.
-- 7월 10일 ~ 7월 19일에 가입한 고객 중
-- 포인트를 가진 고객의 숫자, 그리고 전체 숫자, 그리고 비율
-- 쿼리가 길고 복잡해짐에 따라, 줄 정렬이 중요해진다..!!
select count(pu.point_user_id) as pnt_user_cnt,
count(u.user_id) as user_cnt,
round(count(pu.point_user_id)/count(u.user_id),2) as ration
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'
[ Union ]
[ 동일한 종류의 필드값들을 가진 테이블을, 위-아래로 합쳐서 나타내고 싶은 경우 ]
(
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
)
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
)
UNION을 하는 묶음의 쿼리에서는 ORDER BY가 적용되지 않는다.
위의 쿼리 최적화 관련 포스팅에서, union 대상 쿼리에서 order by 를 사용하면 쓸데없는 연산만 늘어나니 하지 말라고 한 것과 일맥상통한다.
추후 서브쿼리를 배우게 되면, union 한 결과 테이블을 쉽게 정렬할 수 있다고 한다.