[SPARTA CODING] SQL WEEK 3 - Join๊ณผ Union ๐Ÿฆ‹

์ง€์ฝ”ยท2022๋…„ 5์›” 19์ผ
1

SPARTA CODING

๋ชฉ๋ก ๋ณด๊ธฐ
2/6

22/05/02 ~ 22/05/12
๋งˆ์ง€๋ง‰ ์ฃผ์ฐจ์ธ 4์ฃผ์ฐจ์— 3์ฃผ์ฐจ ๋งˆ๋ฌด๋ฆฌํ•˜๋Š” ๊ฒŒ์œผ๋ฆ„๋ฑ…์ด ๋‚˜ #~#

3์ฃผ์ฐจ๋ฅผ ์‹œ์ž‘ํ•ด๋ณด์•˜๋‹ค. 3์ฃผ์ฐจ์˜ ํ•ต์‹ฌ์€ ์ชผ์ธ(join) !


๐Ÿ“š Join ์ด๋ž€ ?

๐Ÿ”น ํ•ฉ์น˜๊ณ ์ž ํ•˜๋Š” ๋‘ ํ…Œ์ด๋ธ”์— ์žˆ๋Š” ๊ณตํ†ต๋œ ํ•„๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•˜์—ฌ ํ•œ ํ…Œ์ด๋ธ”์ฒ˜๋Ÿผ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ !
๐Ÿ”น ์ด ๋•Œ ์ด ๊ณตํ†ต๋œ ํ•„๋“œ๋ฅผ 'key' ๐Ÿ”‘ ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค !

Join์—๋Š” ๋‘ ๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋Š”๋ฐ,
1๏ธโƒฃ Left Join
2๏ธโƒฃ Inner Join
'Left Join'์€ ์ฒซ ๋ฒˆ์งธ ํ…Œ์ด๋ธ”์— ๋ถ™์ด๋Š” ๊ฒƒ์ด๊ณ , (๋”ฐ๋ผ์„œ ์ˆœ์„œ๊ฐ€ ์ค‘์š” โญ๏ธ)
'Inner Join'์€ ๊ต์ง‘ํ•ฉ ๊ฐœ๋…์œผ๋กœ,
์ด ์ค‘์—์„œ ๋‚˜๋Š” Inner Join์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜์˜€๋‹ค ! ๐Ÿ˜š
์„ ์ƒ๋‹˜๊ป˜์„œ๋„ Left Join๋ณด๋‹ค๋Š” Inner Join์„ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๊ณ  ํ•˜์…จ๋‹ค. ๐Ÿ‘จ๐Ÿปโ€๐Ÿซ


๐Ÿ“Œ chapter3-2 ๋‹จ์ˆœํžˆ ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ” ์—ฐ๊ฒฐํ•ด๋ณด๊ธฐ
๋‚ด๊ฐ€ Inner Join์„ ์ฒ˜์Œ ๋ฐฐ์šฐ๊ณ  ๋ฌธ์ œ๋ฅผ ํ’€๋ฉด์„œ ๊ฐ€์žฅ ๋งŽ์ด ๋†“์ณค๋˜ ๋ถ€๋ถ„์€ alias(๋ณ„์นญ)์ด์—ˆ๋‹ค !

๊ฐ€๋ฒผ์šด ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜ ๋ณด์ž.

select * from checkins c 
inner join users u on c.user_id = u.user_id 

1๏ธโƒฃ ์ง€๋‚œ 2์ฃผ์ฐจ๊นŒ์ง€ ๊ณต๋ถ€ํ–ˆ๋˜ SQL์˜ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ๋งŒ ๋ณด๋ฉด ์ฒซ ์ค„์€ 'checkins' ํ…Œ์ด๋ธ”์„ ๊ฐ€์ ธ์˜จ๋‹ค๋Š” ์˜๋ฏธ ! checkins ๋’ค์— ์žˆ๋Š” 'c'๊ฐ€ ์ด ํ…Œ์ด๋ธ”์˜ ๋ณ„์นญ์ด๋‹ค.
2๏ธโƒฃ ๋‘ ๋ฒˆ์งธ ์ค„์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚ด๋ฉด
inner join ํ…Œ์ด๋ธ”๋ช… ํ…Œ์ด๋ธ” ๋ณ„์นญ on ์—ฐ๊ฒฐ ๊ธฐ์ค€์ธ key๊ฐ’ ํ‘œํ˜„
์ด๋ ‡๊ฒŒ ๋‚˜์™€ ์žˆ๋‹ค.
โญ๏ธJoin์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” key๊ฐ’ ํ‘œํ˜„์„ ํ•  ๋•Œ alias๊ฐ€ ํ•„์ˆ˜์ ์ด๋ฏ€๋กœ ๊ผญ ์ฑ™๊ฒจ์•ผ ํ•œ๋‹ค โ—๏ธ


๐Ÿ‘‰๐Ÿป ์‘์šฉ ๋ฌธ์ œ 1๏ธโƒฃ

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

๐Ÿ”น ์ฟผ๋ฆฌ ์‹คํ–‰ ์ˆœ์„œ : from โžก๏ธ join โžก๏ธ group by โžก๏ธ select
๐Ÿ‘จ๐Ÿปโ€๐Ÿซ "๋ชจ๋“  ๊ฐœ๋ฐœ์ž๋“ค์ด ๋‹ค SQL์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค, ์‹คํ–‰ ์ˆœ์„œ์— ๋”ฐ๋ผ ์ฐจ๊ทผ ์ฐจ๊ทผ ํ•˜๋ฉด ๋œ๋‹ค !"
๐Ÿ”น ๊ฐ„๋‹จ ์š”์•ฝ
1) select * from checkins c1์œผ๋กœ ์‹œ์ž‘
2) courses c2 ํ…Œ์ด๋ธ”๊ณผ course_id์— ๋Œ€ํ•ด join
3) course_id์— ๋Œ€ํ•ด ๊ทธ๋ฃน ์ง“๊ธฐ (๊ทธ๋ƒฅ key๊ฐ’๋งŒ ์ ์ง€ ๋ง๊ณ  ๊ผญ alias ๋ถ™์ด๊ธฐ !)
4) ์ตœ์ข… result์— ๋‚˜ํƒ€๋‚ผ ํ•„๋“œ๋“ค๋งŒ ์ถ”๋ ค์„œ select ๋’ค์— ๋„ฃ๊ธฐ + as cnt๋„ ๋ณ„์นญ ์„ค์ • !


๐Ÿ‘‰๐Ÿป ์‘์šฉ ๋ฌธ์ œ 2๏ธโƒฃ

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
๐Ÿ”น ์‘์šฉ ๋ฌธ์ œ 1๋ฒˆ์„ ํ’€์–ด๋ดค์œผ๋‹ˆ ๋Œ€์ถฉ ๊ฐ ์˜ค๊ฒ ์ง€ ? ๋ณต์Šตํ•  ๋•Œ๋„ ๋ฐ”๋กœ ์•Œ๊ธฐ๋ฅผ ^_^
๐Ÿ”น ๊ฐ„๋‹จ ์š”์•ฝ
1) select * from orders o ๋กœ ์‹œ์ž‘
2) users u ํ…Œ์ด๋ธ”๊ณผ user_id์— ๋Œ€ํ•ด join
3) o ํ…Œ์ด๋ธ”์˜ email ํ•„๋“œ์—์„œ 'naver.com'์œผ๋กœ ๋๋‚˜๋Š” ์‚ฌ๋žŒ๋งŒ ์ถ”๋ฆฌ๊ธฐ (where - ์กฐ๊ฑด)
4) u ํ…Œ์ด๋ธ”์˜ name ํ•„๋“œ๋กœ ๊ทธ๋ฃน ์ง“๊ธฐ
5) ์ตœ์ข… result์— ๋‚˜ํƒ€๋‚ผ ํ•„๋“œ๋“ค๋งŒ ์ถ”๋ ค์„œ select ๋’ค์— ๋„ฃ๊ธฐ !


๐Ÿ™‹๐Ÿป ์‹ฌํ™” ๋ฌธ์ œ 1๏ธโƒฃ : ๊ฒฐ์ œ ์ˆ˜๋‹จ ๋ณ„ ์œ ์ € ํฌ์ธํŠธ์˜ ํ‰๊ท ๊ฐ’ ๊ตฌํ•ด๋ณด๊ธฐ (point_users ํ…Œ์ด๋ธ”์— orders ํ…Œ์ด๋ธ” ๋ถ™์ด๊ธฐ)

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

๐Ÿ”น ๊ฐ„๋‹จ ์š”์•ฝ
1) select * from point_users pu ๋กœ ์‹œ์ž‘ - point_users ํ…Œ์ด๋ธ” ๋ณด์—ฌ์ฃผ๊ธฐ
2) orders o ํ…Œ์ด๋ธ”๊ณผ user_id์— ๋Œ€ํ•ด join !
3) o ํ…Œ์ด๋ธ”์˜ payment_method ํ•„๋“œ์— ๋Œ€ํ•ด ๊ทธ๋ฃน ์ง“๊ธฐ
4) ์ตœ์ข… result์— ๋‚˜ํƒ€๋‚ผ ํ•„๋“œ๋“ค ์„ ํƒ + avg๋Š” ํ‰๊ท (avarage)์˜ ์•ฝ์ž, round(ํ•„๋“œ, ์ž๋ฆฟ์ˆ˜) : ๋ฐ˜์˜ฌ๋ฆผ


๐Ÿ™‹๐Ÿป ์‹ฌํ™” ๋ฌธ์ œ 2๏ธโƒฃ : ๊ฒฐ์ œํ•˜๊ณ  ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ์œ ์ €๋“ค์„ ์„ฑ์”จ ๋ณ„๋กœ ์„ธ์–ด๋ณด๊ธฐ (enrolleds ํ…Œ์ด๋ธ”์— users ํ…Œ์ด๋ธ” ๋ถ™์ด๊ธฐ)

select 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

โœ… ์—ฌ๊ธฐ์„œ ํ‹€๋ ธ๋˜ ์  ์งš๊ณ  ๋„˜์–ด๊ฐ€๊ธฐ
1) count(name) -> count(*)
2) is_registered = 0 -> e.is_registered
(๋ณ„์นญ ๊ผญ ๋ถ™์ด๊ธฐโ—๏ธ)


๐Ÿ™‹๐Ÿป ์‹ฌํ™” ๋ฌธ์ œ 3๏ธโƒฃ : ๊ณผ๋ชฉ ๋ณ„๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ์œ ์ €๋“ค ์„ธ์–ด ๋ณด๊ธฐ (courses ํ…Œ์ด๋ธ”์— enrolleds ๋ถ™์ด๊ธฐ)

select c.course_id, c.title, count(*) as cnt_notstart from courses c 
inner join enrolleds e on c.course_id = e.course_id 
where e.is_registered = 0
group by c.course_id

โœ… ์—ฌ๊ธฐ์„œ ํ‹€๋ ธ๋˜ ์  ์งš๊ณ  ๋„˜์–ด๊ฐ€๊ธฐ
1) sรฉlect course_id -> sรฉlect c.course_id (๋ณ„์นญ ๊ผญ ๋ถ™์ด๊ธฐโ—๏ธ)
2) where ์กฐ๊ฑด ์ ˆ ๋จผ์ € ์“ฐ๊ณ  group by๋กœ ๋ฌถ์–ด์ฃผ๊ธฐ


๐Ÿ™‹๐Ÿป ์‹ฌํ™” ๋ฌธ์ œ 4๏ธโƒฃ : ์›น ๊ฐœ๋ฐœ, ์•ฑ ๊ฐœ๋ฐœ ์ข…ํ•ฉ๋ฐ˜์˜ week ๋ณ„ ์ฒดํฌ์ธ ์ˆ˜๋ฅผ ์„ธ์–ด๋ณด๊ณ  8์›” 1์ผ ์ดํ›„์— ๊ตฌ๋งคํ•œ ๊ณ ๊ฐ๋“ค๋งŒ ๋ฐœ๋ผ๋‚ด์–ด ๋ณด๊ธฐ ! (courses ํ…Œ์ด๋ธ”์— checkins ํ…Œ์ด๋ธ” ๋ถ™์ด๊ณ  orders ํ…Œ์ด๋ธ” ํ•œ ๋ฒˆ ๋” ๋ถ™์ด๊ธฐ) โญ๏ธ์–ด๋ ค์›€โญ๏ธ

select 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 
order by c1.title, c2.week 

๐Ÿ”น ์ฒดํฌํ•ด์•ผ ํ•  ๋ถ€๋ถ„
1) ์ด๋ฏธ ์ด์–ด๋ถ™์ธ ๋‘ ํ…Œ์ด๋ธ”์— ๋˜ ํ•˜๋‚˜์˜ ํ…Œ์ด๋ธ”์„ ๋ถ™์ผ ๋•Œ, ์ถ”๊ฐ€๋กœ inner join์„ ์ ์šฉํ•˜๋ฉด ๋œ๋‹ค ! ์—ฌ๊ธฐ์„œ key ๊ฐ’๐Ÿ”‘์„ ์ฒดํฌํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š” !
2) where ์กฐ๊ฑด ์ ˆ ๋จผ์ € ์“ฐ๊ณ  group by, order by ์ ์šฉํ•ด์ฃผ๊ธฐ
3) ๋‚ ์งœ๋Š” '' ์•ˆ์— ์ ์–ด์ฃผ๊ธฐ


๐Ÿ“Œ chapter3-7 ' Left Join' ์จ๋ณด๊ธฐ !
Q. 7์›”10์ผ ~ 7์›”19์ผ์— ๊ฐ€์ž…ํ•œ ๊ณ ๊ฐ ์ค‘,
ํฌ์ธํŠธ๋ฅผ ๊ฐ€์ง„ ๊ณ ๊ฐ์˜ ์ˆซ์ž, ๊ทธ๋ฆฌ๊ณ  ์ „์ฒด ์ˆซ์ž, ๊ทธ๋ฆฌ๊ณ  ๋น„์œจ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ

select count(pu.point_user_id) as pnt_user_cnt, 
	   count(u.user_id) as tot_users_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'

๐Ÿ”น ์ฒดํฌํ•ด์•ผ ํ•  ๋ถ€๋ถ„
1. count๋Š” NULL์„ ์„ธ์ง€ ์•Š์œผ๋ฏ€๋กœ ์ „์ฒด ์ˆซ์ž๋ฅผ ์…€ ๋•Œ NULL์ด ์žˆ๋Š” ํ•„๋“œ๋ฅผ ์„ธ์–ด์ฃผ๋ฉด ๋œ๋‹ค โญ๏ธ
2. between์€ A๋ถ€ํ„ฐ B๊นŒ์ง€์ผ ๋•Œ, between A and B+1 ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•œ๋‹ค.


๐Ÿ“Œ chapter3-8 Union ์‚ฌ์šฉํ•ด๋ณด๊ธฐ !
๐Ÿ‘‰๐Ÿป Union์€ select๋ฅผ ๋‘ ๋ฒˆ ํ•˜์ง€ ์•Š๊ณ  ํ•œ ๋ฒˆ์— ๋ณด๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค ~


์œ„์™€ ๊ฐ™์€ ๋ชจ์Šต์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์•˜๋‹ค.

(
	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
	order 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
	order by c1.title, c2.week
)

๊ฐ€์šด๋ฐ ์žˆ๋Š” union all์ด ํฌ์ธํŠธ !
ํ•˜๋‚˜ ๋” ์ฒดํฌํ•ด์•ผ ํ•  ๊ฒƒ์€ order by๋ฅผ ํ•œ ์ƒํƒœ๋กœ ํ•ฉ์น˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์—†๊ณ , ํ•ฉ์นœ ํ›„์— ์ „์ฒด์—์„œ order by๋ฅผ ํ•ด์ค˜์•ผ ํ•œ๋‹ค !


๐Ÿ“Œ 3์ฃผ์ฐจ homework : enrolled_id๋ณ„ ์ˆ˜๊ฐ•์™„๋ฃŒ(done=1)ํ•œ ๊ฐ•์˜ ๊ฐฏ์ˆ˜๋ฅผ ์„ธ์–ด๋ณด๊ณ , ์™„๋ฃŒํ•œ ๊ฐ•์˜ ์ˆ˜๊ฐ€ ๋งŽ์€ ์ˆœ์„œ๋Œ€๋กœ ์ •๋ ฌํ•ด๋ณด๊ธฐ !
user_id๋„ ๊ฐ™์ด ์ถœ๋ ฅ๋˜์–ด์•ผ ํ•œ๋‹ค.
์ด๋ ‡๊ฒŒ ๋ฐฐ์šฐ๊ณ  ๋‚˜๋‹ˆ ์ˆ™์ œ๋Š” ๊ปŒ์ด์ง€ ! (๊ณผ์—ฐ ?)

๐Ÿฆ‹ ๋Š๋‚€ ์ 
๊ณต๋ถ€ํ•˜๋ฉด์„œ ์–ด๋ ค์šด ๋ถ€๋ถ„๋“ค์ด ์กฐ๊ธˆ์”ฉ ์ƒ๊ธฐ๋‹ค๋ณด๋‹ˆ ์ด๊ฒŒ ๋ฐ”๋กœ SQL์ธ๊ฐ€ ? ์‹ถ์œผ๋ฉด์„œ๋„, ๋งˆ์ง€๋ง‰์œผ๋กœ ๋‚จ์€ 4์ฃผ์ฐจ ๊ณต๋ถ€๋ฅผ ์ง„ํ–‰ํ•  ์ƒ๊ฐ์— ๋‘๊ทผ๋‘๊ทผ๋Œ„๋‹ค โค๏ธโ€๐Ÿ”ฅโค๏ธโ€๐Ÿ”ฅโค๏ธโ€๐Ÿ”ฅ
์ง€๊ธˆ ๋ฐฐ์šฐ๋Š” ํ•™๊ต ๊ณผ๋ชฉ ์ค‘ ์•„๋‘์ด๋…ธ๋ฅผ ์ด์šฉํ•˜๋Š” '์–ด๋“œ๋ฒค์ฒ˜ ๋””์ž์ธ'์—์„œ ์šฐ๋ฆฌ ์กฐ๋Š” ๊ตฌํ˜„ ์ œํ’ˆ๊ณผ ์–ดํ”Œ์„ ๋งŒ๋“œ๋Š๋ผ SQL์ด ํ•„์š”ํ–ˆ์„ ๋•Œ๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ, ๊ณต๋ถ€ํ•˜๊ณ  ๋ณด๋‹ˆ ์—ญ์‹œ๋Š” ์—ญ์‹œ ...!
" ์•„๋Š” ๋งŒํผ ๋ณด์ธ๋‹ค " ๋‚จ์€ ํ•œ ์ฃผ์ฐจ๋„ ํ™”์ดํŒ… ๐Ÿ”ฅ

profile
FE ๊ฐœ๋ฐœ์ž ์—ญ๋Ÿ‰์„ ํ‚ค์›Œ๋ณด์ž !

0๊ฐœ์˜ ๋Œ“๊ธ€