SQL (3)

김재익·2023년 6월 13일
0
post-thumbnail

JOIN의 종류

INNER JOIN
LEFT JOIN
종류가 더 있지만 배운건 위 두 가지

INNER JOIN

A테이블과 B테이블의 공통된 부분을 출력

ex) 같은 성씨를 가진 네이버 이메일로 주문한 사람들의 수
SELECT u.name, COUNT(*) as cnt FROM orders o
INNER JOIN users u
ON o.user_id = u.user_id
WHERE o.email LIKE '%naver.com'
GROUP BY u.name;

쿼리가 실행되는 순서: from → join → where → group by → select

테이블 세개를 연결하는법

ex) 각 반의 8월 1일 이후 week별 체크인 수 통계
SELECT co.title, ch.week, COUNT(*) as cnt  FROM checkins ch
INNER JOIN courses co
ON ch.course_id = co.course_id
INNER JOIN orders o
ON ch.user_id = o.user_id
WHERE o.created_at >= '2020-08-01'
GROUP BY co.title, ch.week
ORDER BY co.title, ch.week

그냥 조인을 두번 쓰면 된다.

LEFT JOIN

INNER JOIN과 달리 기준이 되는 테이블을 잘 정해야함

A테이블과 B테이블을 비교해서 A가 가진 값이 B에도 있는 경우를 포함하여 출력하고 A가 가진 값이 B에 없는 경우는 NULL로 표시한다

ex) 가입은 되어있어서 B에 user id가 있긴하지만 강의를 시작한 이력이 없어서 point가 없는 경우
SELECT u.user_id, pu.point_user_id from users u
left join point_users pu on u.user_id = pu.user_id;

ex) 가입은 했지만 강의 시작은 안한사람 성씨별로
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 COUNT(*) DESC;

IS NULL 로 시작 안한사람 구할 수 있고
IS NOT NULL 로 시작한 사람을 구할 수 있다.

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'

COUNT는 NULL은 자동으로 안센다

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
)
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가 먹히지 않는다.
정렬을 하려면 서브쿼리라는 개념을 이용해야한다.

profile
개발자호소인

0개의 댓글