[내일배움캠프 사전공부 SQL 3주차]

안떽왕·2023년 2월 18일
0

JOIN

두 개의 테이블을 연결
LEFT JOIN과 INNER JOIN이 주력

LEFT JOIN

왼쪽 테이블을 중심으로 오른쪽의 테이블을 매치
왼쪽 테이블의 한개의 레코드에 여러개의 오른쪽 테이블 레코드가 일치할 경우, 해당 왼쪽 레코드를 여러번 표시
왼쪽은 무조건 표시하고, 매치되는 레코드가 오른쪽에 없으면 NULL을 표시

SELECT * FROM users u 
LEFT JOIN point_users pu
ON u.user_id = pu.user_id

users를 u라고 칭함
point_users를 pu라고 칭하고 left join하는데 u에 있는 user_id필드와 pu에 있는 user_id를 기준으로 left join
모든정보 불러옴
순서는 from → join → select

INNER JOIN

왼쪽 테이블을 중심으로 오른쪽의 테이블을 매치
왼쪽을 무조건 표시하고 매치되는 레코드가 오른쪽에 없으면 넘어감

SELECT * FROM users u 
inner JOIN point_users pu
ON u.user_id = pu.user_id

LEFT JOIN의 설명과 같음

checkin과 courses를 연결해 갯수 세어보기

SELECT c1.course_id, c2.title, COUNT(*) AS cnt FROM checkins c1
INNER JOIN courses c2 ON c1.course_id = c2.course_id
GROUP BY c1.course_id

point_users 테이블에 users 테이블 연결해서 정렬해보기

SELECT pu.user_id, u.name, u.email, pu.point  FROM point_users pu
INNER JOIN users u on pu.user_id = u.user_id
ORDER BY pu.point desc

네이버 이메일을 사용하는 유저의 성씨별 주문건수

SELECT u.name, COUNT(*) AS cnt FROM orders o 
INNER JOIN users u ON o.user_id = u.user_id
WHERE o.email LIKE '%naver.com'
GROUP BY u.name

실행순서
from → join → where → group by → select

웹개발, 앱개발 종합반의 week별 체크인 수 세고 정렬

SELECT c1.title, c2.week, COUNT(*)  FROM courses c1 
INNER JOIN checkins c2 on c1.course_id = c2.course_id
GROUP BY c1.title, c2.week
ORDER BY c1.title, c2.week

,를 통해 그룹바이 오더바이 모두 2개 이상 가능
위의 결과에서 8월 1일 이후에 구매한 고객만 추리기

SELECT c1.title, c2.week, COUNT(*) 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

inner join을 하나 더 만들고 on 뒤에 c2를 이음으로써 만듬

LEFT JOIN 해보기

없는걸 기준으로 통계를 낼때 유용함

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

users와 point_users를 left join 해주고 user_id로 연결
where문을 통해 pu에 있는 point_user_id 가 null값인 것만 찾음
u에 있는 name으로 그룹짓고 select 에서 u의 name과 count를 적게되면
성씨별 null값의 통계를 낼 수 있다.

7월 10일 ~ 19일에 가입한 고객 중, 포인트를 가진 고객의 숫자, 전체 숫자, 비율을 소숫점 2째자리까지 표시하라 각각의 컬럼명도 표시할것

SELECT COUNT(pu.point_user_id) AS pnt_user_cnt,
       COUNT(u.user_id) AS tot_user_cnt,
       ROUND(COUNT(pu.point_user_id) / 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'

※ count는 null값을 세지 않는다.

UNION

예를 들어 7월자료와 8월자료가 있을때 함께 보기위해 쓰는 문구
union에 있으면 order가 먹지 않는다, 합친다음에 해야 가능

(
	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
)

3주차 숙제

Join/Subquery을 사용하여 유저별로 수강완료한 강의 수를 세어보고, 완료한 강의 수가 많은 순서대로 정렬해보기

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 ed.enrolled_id, e.user_id
ORDER BY max_count DESC ![](https://velog.velcdn.com/images/william741/post/1e92062b-2268-49c0-88e5-de4b14e74ac7/image.png)
profile
이제 막 개발 배우는 코린이

0개의 댓글