Join = 두 테이블의 공통된 정보 (key값)를 기준으로 테이블을 연결해서 한 테이블처럼 보는 것
inner join = 공통된 key값의 교집합 기준
left join = 공통되지 않은 key값도 포함(NULL) → 어디에 어떤 필드를 넣는 순서가 중요
ex)
select * from enrolleds e
inner join courses c
on e.course_id = c.course_id;
위 쿼리가 실행되는 순서: from → join → select
select * from enrolleds e
inner join courses c
on e.course_id = c.course_id;
select o.payment_method, round(avg(pu.point),0) from point_users pu
inner join orders o
on pu.user_id = o.user_id
group by o.payment_method
select c.title, e.week, count(*) as cnt from courses c
inner join checkins e
on c.course_id = e.course_id
group by c.title, e.week
order by c.title, e.week
select c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders c3 on c2.user_id = c3.user_id
where c3.created_at > ‘2020–08–01’
group by c1.title, c2.week
order by c1.title, c2.week
같은 결과에 도달할 수 있는 방법이 여러가지
반드시 하나의 쿼리가 정답은 아니다.
이렇게 해봤다가 저렇게 해봤다가
왔다갔다 하면서 만드는 것. 한 번에 쭉 위에서 써서 탁 실행시키는 경우 없음
결국 모로가도 데이터만 나오면 된다.
한쪽에는 있는데 한쪽에는 없는 데이터로 통계내고자 할 때
ex)강의는 했지만 강의시작 안 한 사람
select count(pu.point_user_id) as pnt_user_cnt,
count(u.user_id) as tot_user_cnt,
round(count(pu.point_user_id)/count(u.user_id),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’
Union
필드가 다 똑같을 때, 그대로 두 필드를 붙여줄 때
ex)
(
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에서는 Order가 작용하지 않음
그래서 이걸 다시 정렬 → 서브쿼리