SQL 3주차 일지

최창수·2023년 2월 23일
0

SQL

목록 보기
3/5
post-thumbnail

들어가기 앞서

데이터들은 보통 여러 table로 나뉘어 있다.

웹 서비스를 더 원활하게 작동하게 하기 위해서 '한가지 목적에 맞는' 데이터들만 한개의 table에 모아두는 것이 좋기 때문이다. 예를 들어 회원정보(email 주소, 생년월일 등)와 회원의 활동내역(작성 댓글 등)은 분리하여 저장하는 것이 좋을 것이다. 그러나 여러 table을 함께 참조해야 하는경우 join등을 사용해 하나의 table로 연결하여 insight를 얻는데 활용할 수 있다.

1. SQL syntax - join

join은 excel의 vlookup과 동일한 기능이다. 두 table에 같은 field가 존재한다면, 같은 field를 기준으로 두 테이블을 횡으로 이어붙이는 역할을 한다.
join은 from 구문 바로 다음에 쓴다.
실행순서는 from절 바로 다음이며, 이후 실행순서는 2주차에서 배운것과 동일하다. 다음과 같은 형식으로 사용한다.

select A.[field 명], B.[field명]
from [table1 명] A inner join [table2 명] B on A.[기준 field명] = B.[기준 field명]

join 사용시에는 어느 table의 어느 field인지 명시해줄 필요가 있으므로 alias(별칭)을 사용한다.
join에는 inner join과 left join이 존재하며 inner join이 기본이라고 할 수 있다.

  • inner join: 교집합 개념과 유사하다. 어떤 record의 field의 값이 두 테이블중 하나만이라도 없다면 결과에 포함되지 않는다. 따라서 비어있는 field가 없다.
  • left join: [table 1]에 존재하는 field 값을 기준으로 하여 합친다. 어떤 record의 해당 field의 값이 [table 2]에는 없는 경우, 두번째 테이블에 있던 field들은 NULL로 채워넣는다. [table 2]에는 있지만 [table 1]에는 없는 경우는 결과에 포함되지 않는다. 왼쪽 테이블의 한개의 record에 여러개의 오른쪽 테이블 레코드가 일치할 경우, 해당 왼쪽 record를 여러번 표시하게 된다.

left join을 이용하면 [table 1]에는 있지만 [table 2]에는 없는 경우 NULL이 생기는 것과, count() 가 NULL은 갯수로 치지 않는 것을 이용하면, 유용한 통계값을 만들 수 있다. 예를 들어 전체 회원중 프리미엄 서비스에 가입한 회원 비율 등을 파악하는데 활용할 수 있다.

count([field명])/count(*) as ratio

NULL을 where절에서 사용할 경우, =!=가 아닌 is,is not을 사용하면 된다.

2. 다중 field Group/Order py

,를 이용하여 여러 개의 field를 기준으로 범주화/ 정렬이 가능하다.
order by의 경우 각 field 마다 따로 desc asc 지정하는 것도 가능하다.

select c1.title, c2.week, count(*) as cnt from checkins c2
inner join courses c1 on c2.course_id = c1.course_id
group by c1.title, c2.week
order by c1.title, c2.week

3. Union

두 테이블이 정확히 같은 field 들로 구성되어있다면 둘을 Union을 통해 종으로, 즉 record를 밑에 붙이는 형식으로 합칠 수 있다.
Union의 사용 방법은 다음과 같다.

(쿼리문 1)
union all
(쿼리문 2)

예시:

(
	select '7월' as month, c.title, c2.week, count(*) as cnt from checkins c2
	inner join courses c on c2.course_id = c.course_id
	inner join orders o on o.user_id = c2.user_id
	where o.created_at < '2020-08-01'
	group by c2.course_id, c2.week
  order by c2.course_id, c2.week
)
union all
(
	select '8월' as month, c.title, c2.week, count(*) as cnt from checkins c2
	inner join courses c on c2.course_id = c.course_id
	inner join orders o on o.user_id = c2.user_id
	where o.created_at >= '2020-08-01'
	group by c2.course_id, c2.week
  order by c2.course_id, c2.week
)

다만 정렬은 새로운 합쳐진 테이블에 적용되지 않는다. 이것을 해결하기위해선 앞으로 배울 subquery를 이용해야한다.

profile
Hallow Word!

0개의 댓글