Join을 사용하면 두 테이블의 공통된 정보(key)를 기반으로 테이블을 연결할 수 있습니다.
오늘은 자주 사용되는 Innter Join과 Left join에 대해 알아보겠습니다.
Left Join (Outer Join)
Left Join에서는 어떤 테이블을 기준으로 join을 할 것인가가 중요합니다.
기준이 되는 테이블이 A라면, A에 B 테이블을 붙이게 되는데, A에 B에 관한 내용이 없으면 필드값이 NULL이 됩니다.
store 테이블의 id 값과 동일한 id 값을 갖는 reivew 테이블을 join 하려면 다음과 같이 작성합니다.
select * from store s
left join review r on s.id = r.id
디저트집에 대한 review가 존재하지 않기 때문에 NULL로 표시됩니다.
따라서 Left Join을 그림으로 표현하면 다음과 같습니다.
다른 예시를 더 살펴보겠습니다.
1. users 테이블과 point_users 테이블을 Left Join
users 테이블과, points 테이블이 있고, user는 처음 강의를 수강하기 전까지 points_users 테이블에 데이터가 없다고 합시다.
users 테이블에 points 테이블을 Left join하면 해당 user의 point 테이블 필드는 모두 NULL이 뜰 것 입니다.
select u.user_id, u.name, pu.point from users u
left join point_users pu on u.user_id = pu.user_id
그렇다면 NULL을 이용해서 강의를 한 번도 수강하지 않은 사람들을 통계낼 수 있을 것입니다.
select u.user_id, 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
2. 2020-7-10 ~ 202-7-19 에 가입한 고객 중, 포인트를 가진 user의 숫자, 전체 회원 숫자, 비율구하기
포인트가 없는 user는 point_user_id 값도 NULL을 갖게 됩니다.
NULL이 아닌 user만 뽑아서 count를 해야하나 생각할 수 있지만, count()를 하면 NULL을 제외하고 세어주기 때문에 다른 조건을 걸지 않아도 됩니다.
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'
Inner Join
enrolleds 테이블의 course_id 값과 동일한 course_id 값을 갖는 courses 테이블을 join 하려면 다음과 같이 작성합니다.
select * from enrolleds e
inner join courses c on e.course_id = c.course_id
기준 테이블인 enrolleds의 course_id필드에 course4는 없기 때문에 join 결과에 포함되지 않습니다.
따라서 Inner Join을 그림으로 표현하면 다음과 같습니다.
다른 예시를 더 살펴보겠습니다.
1. 결제 수단 별 유저 포인트의 평균값 구하기
이때, 결제 수단 데이터는 orders 테이블에 있고, 포인트 데이터는 point_users 테이블에 있습니다.
select o.payment_method, round(avg(pu.point)) from point_users pu
inner join orders o on pu.user_id = o.user_id
group by o.payment_method
2. 웹개발, 앱개발 종합반의 week별, 체크인 수 세어보기
이때, week 데이터는 checkins 테이블에, 과목 데이터는 courses 테이블에 있고, 과목은 앱개발과 웹개발만 있습니다.
과목별, 주차별로 수를 세어주어야 하므로 콤마(,)를 사용해서 group by 해줍니다.
select c2.title , c1.week, count(*) as cnt from checkins c1
inner join courses c2 on c1.course_id = c2.course_id
group by c2.title, c1.week
order by c2.title, c1.week
3. 웹개발, 앱개발 종합반의 week별, 2020년 8월 1일 이후 강의를 구매한 유저 수 세기
강의 구매 날짜 정보는 orders 테이블에 있습니다. 따라서 2번 예시에서 orders 테이블을 join하여 구할 수 있습니다.
select c2.title, c1.week, count(*) as cnt from checkins c1
inner join courses c2 on c1.course_id = c2.course_id
inner join orders o on c1.user_id = o.user_id
where o.created_at >= '2020-08-01'
group by c2.title, c1.week
order by c2.title, c1.week
'DB > SQL' 카테고리의 다른 글
[DB/SQL] SubQuery - Select, Where, From절에서 사용하기 (0) | 2023.03.21 |
---|---|
[DB/SQL] UNION, UNION ALL 쿼리 결과 합치기 (0) | 2023.03.21 |
[프로그래머스/SQL] 3월에 태어난 여성 회원 목록 출력하기 (0) | 2023.03.21 |
[SQL] DATE_FORMAT 날짜/시간 포맷 지정하기 (0) | 2023.03.21 |
[DB/SQL] Order by 오름차순/내림차순 정렬하기 (0) | 2023.03.20 |