Weekly I Learned (SQL, 12/20–12/26)
[수업 목표]
- 여러 테이블의 정보를 연결하는 Join을 이해한다.
- 연결된 정보를 바탕으로 보다 풍부한 데이터분석을 연습한다.
- 아래 위로 결과를 연결하는 Union을 공부한다.
Join이란? 두 테이블의 공통된 정보 (key값)를 기준으로 테이블을 연결해서 한 테이블처럼 보는 것
Left Join
Inner Join
연결의 기준이 되고싶은 테이블을 from 절에, 기준이 되는 테이블에 붙이고 싶은 테이블을 Join 절에
select * from enrolleds e
inner join courses c on e.course_id = c.course_id;
위 쿼리가 실행되는 순서: from → join → select
- from enrolleds: enrolleds 테이블 데이터 전체를 가져옵니다.
- inner join courses on e.course_id = c.course_id: courses를 enrolleds 테이블에 붙이는데, enrolleds 테이블의 course_id와 동일한 course_id를 갖는 courses의 테이블을 붙입니다.
- select * : 붙여진 모든 데이터를 출력합니다.
과목 별로 시작하지 않은 유저들 세어보기
내가 작성한 쿼리
select c.course_id, c.title, count(*) from courses c
inner join enrolleds e
on c.course_id = e.course_id
where e.is_registered = 0
group by c.title
모범 쿼리
select c.course_id, c.title, count(*) from courses c
inner join enrolleds e
on c.course_id = e.course_id
where is_registered = 0
group by c.course_id
내 쿼리의 문제점
❌ course 테이블의 title 은 중복값이 존재할 수 있음
⭕️ 중복을 피하기 위해 고유값만 존재하는 course_id 사용
숙제: enrolled_id별 수강완료(done=1)한 강의 갯수를 세어보고, 완료한 강의 수가 많은 순서대로 정렬해보기. user_id도 같이 출력되어야 한다.
숙제: enrolled_id별 수강완료(done=1)한 강의 갯수를 세어보고, 완료한 강의 수가 많은 순서대로 정렬해보기. user_id도 같이 출력되어야 한다.
select e.enrolled_id, e.user_id, count(*) 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, e.user_id
order by count(*) desc
⭕️ group by 에서 e.user_id 를 넣어야 하는 이유 (내가 처음 작성한 쿼리에서 select 문에만 e.user_id 넣어줌)
: group by 로 묶은 기준도 아니고 집계함수도 적용되지 않은 컬럼에서 중복 데이터가 발생할 경우 대표값이 랜덤으로 뽑힐 수 있기 때문. 동일한 enrolled_id 를 가진 데이터에 서로 다른 user_id 가 있다면 무작위로 대표값이 뽑히게 됨. 그래서 알 수 없는 데이터가 나오는 것을 방지하기 위해 되도록 user_id 도 서로 다른 값이 있다면 서로 대표값이 되어 나눠지도록 group by 키로 작성해주는 것.