SQL 강의 정리/3주차

3주차 left join

황소탄 2023. 2. 17. 20:25

2023-02-17(금) 16:35

어제 강의로 left join과 서브쿼리, with 사용 방법을 배웠습니다. left join은 큰 문제가 없었지만 서브쿼리로 넘어오니 머리가 핑핑 도네요 

 

상황에 따라 where, select, from 구분하여 서브쿼리를 적용시켜야 하는데

뭐가 뭔지 모르겠고 뭘 모르는지 모르고 그냥 다 모르겠다! 총체적 난국을 맞이하여 오늘 강의를 통해 퀴즈와 함께 어찌어찌 이해 비슷하게 하고 왔습니다

 

일단 3주차 수업 마지막을 장식할 left join부터 시작해 보겠습니다

left join은 

main이 되는 테이블을 기준으로 join시킵니다

 

그렇기에 B에 해당하는 테이블에서 A에 관한 컬럼이 없다면 그 부분은 null 값을 가지게 됩니다

ex) 회원정보 테이블과 회원 포인트 테이블을 회원 아이디로 join했을 시 포인트가 없는 회원의 포인트 칸은 null값을 가집니다

users 테이블과 point_users 테이블을 join 시켰습니다 

 

그렇다면 left join을 어떻게 사용해야 할까요?

스파르타에서 포인트를 얻기위해서는 강의를 수강하여야 합니다 즉, 포인트가 없다는 것은 강의를 듣지 않았다 는 것을 의미합니다

회원의 성씨 별 로 그룹을 만들어 null 값을 이용하여 성씨 별 수강 정도를 알아봅시다

select name, count(*) from users u
left join point_users pu on u.user_id = pu.user_id
where pu.point_user_id is not NULL
group by name

users 테이블과 point_users 테이블을 user_id 컬럼으로 join 시켰습니다

위와 같이 포인트가 없는 회원의 경우 point_users 테이블에 기록되지 않았기에 join으로 합쳐진 테이블에는 null값으로 출력됩니다

where절을 이용하여 pu(point_users)테이블에서 user_id가 NULL값이 아닌 회원을 뽑습니다(포인트를 가진 회원을 뽑기위해서 입니다)

 

*NULL이 아니다를 표현할 때에는 is not NULL을 사용합니다 그렇다면 반대로 NULL이다는 어떻게 표현할까요?

where pu.point_user_id =NULL? 아닙니다!  where pu.point_user_id is NULL로 표현해야 합니다 

NULL의 특수성이라 생각하면 됩니다!

 

성씨 별로 묶어야 하니 name으로 그룹화 시킵니다

출력할 부분은 name과 그룹된 name별 null이 아닌 것의 수 입니다

출력되었습니다 

 

문제 하나 더 풀어보겠습니다

7월10일 ~ 7월19일에 가입한 고객 중, 포인트를 가진 고객의 숫자, 그리고 전체 숫자, 그리고 비율을 구해봅시다

포인트를 가진 고객의 숫자는 pnt_user_cnt로 전체 고객의 숫자는 tot_user_cnt 비율은 ratio로 Alias를 이용하여 변경합니다

select count(point_user_id) as pnt_user_cnt,
          count(*) as tot_user_cnt,
          round(count(point_user_id)/count(*),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'

이번에는 단계별로 봅시다 먼저 join할 두 테이블을 봅니다 

select * from users u

select * from point_users pu

 

users 테이블에서는 created_at(가입날짜) 컬럼이 필요하고 두 테이블 모두 user_id를 가지고 있으니 이것을 이용하여 join 시킵니다

select * from users u

left join point_users pu

on u.user_id = pu.user_id 

두 테이블의 조인이 완료되었습니다 문제를 보면 7월 10일부터 7월 19일 까지 가입한 고객이 조건입니다

where절에서 between을 이용합니다

select * 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'

실행시켜보면 해당 범위의 값들만 출력됩니다 

 

select문을 완료합시다 

출력시켜야 하는 것은 포인트를 가진 회원의 수, 전체 회원의 수, 그리고 비율입니다

 

포인트를 가진 회원의 수는 

select count(pu.point_user_id) <-이렇게 하여 뽑습니다 as를 이용하여 필드명을 pnt_user_cnt 이것으로 바꿔줍니다

select count(pu.point_user_id) as pnt_user_cnt,

다음은 전체 회원의 수입니다

count(*) 을 사용하면 됩니다 마찬가지로 as를 사용하여 필드명을 변경합니다

count(*) as tot_user_cnt,

두 필드의 비율을 구합시다

count(pu.point_user_id)/count(*) 소수점 2번째 자리까지 표현해야하니 round를 이용하여 줍니다

round(count(pu.point_user_id)/count(*),2) 마찬가지로 as를 통해 필드명을 변경해 줍니다

round(count(pu.point_user_id)/count(*),2) as ratio

select절을 완성시켜 보겠습니다

select count(point_user_id) as pnt_user_cnt,
          count(*) as tot_user_cnt,
          round(count(point_user_id)/count(*),2) as ratio

전체적으로 붙여보면

select count(point_user_id) as pnt_user_cnt,
          count(*) as tot_user_cnt,
          round(count(point_user_id)/count(*),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'

이렇게 됩니다 

 

이것으로 left join을 마치겠습니다 

 

아직도 서브쿼리가 긴가민가 합니다 

주말동안 강의를 다시 보면서 서브쿼리 개념을 좀 다듬고 일지를 써야겠네요

이제 남은 일지는 서브쿼리와 마지막 숙제 두 가지 남았습니다

주말동안 열공하여 서브쿼리 개념 잡고 오겠습니다!