Key
두 테이블을 연결시켜 주는 열쇠라는 의미로, 두 테이블에 동시에 존재하는 필드.
테이블을 설계할 때 한 테이블에 모든 데이터를 저장할 경우, 불필요하게 테이블 크기가 커지기 때문에
데이터를 종류별로 쪼개 다른 테이블에 담아놓고 'key'를 통해 서로 연결할 수 있도록 만든다
Join
두 테이블의 공통된 정보 (key값)를 기준으로 테이블을 연결해서 한 테이블처럼 보는 것
Join의 종류
Left Join : A에는 있고 B에는 없는 것을 통계내고 싶을 때 사용
어디에 뭐를 붙일건지 순서가 중요
select * from users u
left join point_users p
on u.user_id = p.user_id;
비어있는 데이터: 해당 데이터의 user_id 필드값이 point_users 테이블에 존재하지 않는 경우
쿼리 작성해보기(left join)
is NULL - NULL인 데이터만 출력
is not NULL - NULL이 아닌 데이터만 출력
count는 NULL을 세지 않음
유저 중에, 포인트가 없는 사람(=시작하지 않은 사람들) 세보기
select u.name, count(*) 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
7월 10일 ~ 7월 19일에 가입한 고객 중, 포인트를 가진 고객의 숫자, 전체 숫자, 비율
select count(pu.point_user_id) as '포인트를 가진 고객',
count(*) as '모든 고객',
ROUND(count(pu.point_user_id)/count(*),1) as '비율'
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'
Inner Join
두 테이블에서 모두 가지고 있는 데이터만 출력
select * from users u
inner join point_users p
on u.user_id = p.user_id;
연결의 기준이 되고싶은 테이블을 from 절에, 기준이 되는 테이블에 붙이고 싶은 테이블을 Join 절에 위치
from에 들어간 테이블을 기준으로, 다른 테이블이 붙는다고 생각
쿼리 작성해보기(inner join)
결제 수단 별 유저 포인트의 평균값 구해보기
select o.payment_method, ROUND(AVG(pu.point)) as avg_point from point_users pu
inner join orders o
on pu.user_id = o.user_id
group by o.payment_method
결제하고 시작하지 않은 유저들을 성씨별로 세어보기
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
웹개발, 앱개발 종합반의 week 별 체크인 수를 세어보기
select c.title, h.week, COUNT(*) FROM courses c
inner join checkins h
on c.course_id = h.course_id
GROUP BY c.title, h.week
ORDER by c.title, h.week
위 쿼리에서 8월 1일 이후에 구매한 고객들만 추출하기
select c.title, h.week, count(*) FROM courses c
inner join checkins h on c.course_id = h.course_id
inner join orders o on h.user_id = o.user_id
where o.created_at >= '2020-08-01'
GROUP BY c.title, h.week
ORDER by c.title, h.week
이미 join했던 테이블에 다시 join 할 수 있다.
Union
Select를 두 번 해야 하는 할 때, 보고싶은 데이터의 필드명이 똑같다면 사용 가능
union 사용 시 order by 안됨
(
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
)
'[스파르타 코딩클럽] > 엑셀보다 쉬운, SQL' 카테고리의 다른 글
엑셀보다 쉬운 SQL - With절과 유용한 문법들 - (0) | 2023.02.20 |
---|---|
엑셀보다 쉬운 SQL - Subquery - (0) | 2023.02.20 |
엑셀보다 쉬운 SQL - Group by, Order by, Alias - (0) | 2023.02.10 |
엑셀보다 쉬운 SQL - Where 절과 자주 같이쓰는 문법 - (0) | 2023.02.10 |
엑셀보다 쉬운 SQL - SELECT문 - (0) | 2023.02.10 |