박지홍·2023년 2월 24일
0

#Join 여러 테이블을 연결 할 때 사용
테이블 끼리 연결하기 위해선 공통된 정보를 담은 필드가 필요.
해당 데이터베이스에서는 user_id, course_id 로 사용된다.. Key값의 개념.

exel의 vlookup과 비슷한 개념을 가진다.

Left join, Inner Join으로 구분된다.

Left = [합집합의 개념]
A에 B를 붙여라 B의 키값이 NULL 이면 차집합
Inner = [교집합의 개념]

사용법 left join [붙일 테이블명][별칭] on [기준이될 키값 필드] = [붙여질 키값 필드]
Ex. left join point_users pu on u.user_id = pu.user_id

~연습1. orders 테이블에 users 테이블 연결
SELECT * FROM orders o
inner join users u on o.user_id = u.user_id

~연습2. checkins 테이블에 users 테이블 연결
SELECT * FROM checkins c
inner join users u on c.user_id = u.user_id

~연습3. enrolleds 테이블에 courses 테이블 연결
SELECT * FROM enrolleds e
inner join courses c on e.course_id = c.course_id

쿼리 실행순서.
select * from [A 테이블] A
inner join [B 테이블] B
on A.[Key 필드] = B.[Key 필드]

  1. from [A 테이블] A
    A테이블의 전체 데이터를 가져온다.

  2. inner join [B 테이블] B on A.[Key 필드] = B.[Key 필드]
    B테이블을 A테이블에 연결시키는데 이때,
    A테이블의 [Key 필드]와 동일한 B테이블의 [Key 필드]를 갖는 값만을 A테이블에 붙인다.
    3.Select *
    붙여진 모든 데이터를 출력시킨다.

    ~연습4. 오늘의 다짐 정보에 과목정보를 연걸해 과목별 오늘의 다짐 갯수를 세어보자
    SELECT c2.title , count(*) FROM checkins c
    inner join courses c2 on c.course_id = c2.course_id
    group by c.course_id

    ~연습5. 유저의 포인트 정보가 담긴 테이블에 유저의 정보를 연결해서, 많은 포인트를 얻은 순서대로 유저의 데이터뽑기
    SELECT pu.user_id, pu.point, u.name, u.email from point_users pu
    inner join users u on pu.user_id = u.user_id
    order by pu.point desc

    ~연습6. 주문 정보에 유저 정보를 연결해 네이버 이메일을 사용하는 유저 중, 성씨별 주문건수를 세어보자.
    SELECT u.name, o.email, count(*) FROM orders o
    inner join users u on o.user_id = u.user_id
    where o.email like '%naver.com'
    group by u.name

    ~퀴즈1. 결제 수단 별 유저포인트의 평균값 구하기.
    SELECT o.payment_method, round(avg(pu.point),0) from orders o
    inner join point_users pu on o.user_id = pu.user_id
    group by o.payment_method

    ~퀴즈2. 결제하고 시작하지 않은 유저들을 성씨별로 세어보기.
    SELECT u.name, count(*) as cnt_name from enrolleds e
    inner join users u on e.user_id = u.user_id
    where e.is_registered = 0
    group by u.name
    order by cnt_name desc

    ~퀴즈3. 과목 별로 시작하지 않은 유저들을 세어보기
    SELECT c.title, c.course_id, count(*) as cnt_notstart from courses c
    inner join enrolleds e on c.course_id = e.course_id
    WHERE e.is_registered = 0
    group by c.title

    ~퀴즈4. 웹개발, 앱개발 종합반의 week 별 체크인수를 세어보자.
    SELECT c.title ,c2.week, COUNT(*) as cnt from courses c
    inner join checkins c2 on c.course_id = c2.course_id
    group by c2.week, c.title
    order by c.title, cnt desc

    ~퀴즈5. 연습4번에서 8월1일 이후에 구매한 고객들만 추출하기.
    SELECT c.title ,c2.week, COUNT(*) as cnt from courses c
    inner join checkins c2 on c.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 c2.week, c.title
    order by c.title, cnt desc

    #Left Join 은 좌측 테이블에 붙이는것으로 순서가 중요하다.
    한쪽에는 있으나 다른 한쪽에는 없는 것을 통계내고 싶을 경우
    users에 point_users의 user_id로 묶어준후에
    pu의 user id가 null 값인 사람만을 비교하고 이름으로 정렬하면
    포인트가 없는 사람의 수를 샐수있다.

    ~퀴즈6. 7월10일 ~ 7월 19일에 가입한 고객중 포인트를 가진 고객의 수, 전체 고객수, 그 비율구하기
    SELECT count(u.user_id)as tot, count(pu.point)as pnt, round(count(pu.point)/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'

포인트를 가진 고객의 수를 구하기 위해서는 point나 point_user_id 같이 시작을 안햇다면 Null 값을 지니는 항목을 Count 하고
전체 고객수를 구하기 위해서는 각 고객이 모두 지니는 user_id를 구하면 된다.
그후 전체 고객의 수에서 point나 point_user_id를 가진 고객의 수를 나눠주면 비율이 구해진다.

#UNION
2종류 이상의 쿼리문을 이어서 출력할때 사용한다
쿼리문을 소괄호 ( ) 로 묶어주고 후술되는 쿼리문의 소괄호 ( ) 앞에 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
)
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
)

~숙제1. enrolled_id 별 수강완료 (done==1)한 강의 갯수를 세어보고 완료한 강의수가 많은 순서로 정렬하기
user_id도 같이 출력되어야 한다.

SELECT e.enrolled_id, e.user_id, count(ed.done)as max_count from enrolleds e
inner join enrolleds_detail ed on e.enrolled_id = ed.enrolled_id
where ed.done = 1
group by e.enrolled_id
order by max_count desc

0개의 댓글