Database/SQL

[MySQL] [์ŠคํŒŒ๋ฅดํƒ€์ฝ”๋”ฉํด๋Ÿฝ SQL] Join, Union

Ella_K 2022. 7. 16. 17:51

๐Ÿ”ฅ Join

  • ๋‘ ํ…Œ์ด๋ธ”์˜ ๊ณตํ†ต๋œ ์ •๋ณด(key)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•ด์„œ ํ•œ ํ…Œ์ด๋ธ”์ฒ˜๋Ÿผ ๋ณด๋Š” ๊ฒƒ
  • key: ๋‘ ํ…Œ์ด๋ธ” ๋ชจ๋‘ ๊ฐ–๊ณ  ์žˆ๋Š” ํ•„๋“œ → ๋‘ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๋Š” ์—ด์‡ ๊ฐ€ ๋œ๋‹ค.
  • ์„œ๋กœ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋“ค์„ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ ํ…Œ์ด๋ธ”๋“ค์„ ํ•ฉ์ณ์ค€๋‹ค.

 

๐Ÿ”ฅ Left Join 

๊ฐœ๋…

  • ํ•ฉ์ง‘ํ•ฉ
  • ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ•ฉ์นœ๋‹ค.
  • ๋‘ ํ…Œ์ด๋ธ”์„ ํ•ฉ์น  ๋•Œ keyํ•„๋“œ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ ํ…Œ์ด๋ธ”์—๋Š” ์žˆ๊ณ  ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์—๋Š” ์—†์„ ์ˆ˜ ์žˆ๋‹ค. left join์€ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ•ฉ์น˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด ๊ฒฝ์šฐ ๋น„์›Œ์žˆ๋Š” ๊ณต๊ฐ„์ด ์ƒ๊ธด๋‹ค.
select * from users u
left join point_users p
on u.user_id = p.user_id;

์–ด๋–ค ๋ฐ์ดํ„ฐ(ํ•œ ํ–‰)๋Š” ๋ชจ๋“  ํ•„๋“œ๊ฐ€ ์ฑ„์›Œ์ ธ ์žˆ์ง€๋งŒ, ์–ด๋–ค ๋ฐ์ดํ„ฐ๋Š” [Null]๋กœ ๋น„์–ด์žˆ๋Š” ํ•„๋“œ๊ฐ€ ์žˆ๋‹ค.
usersํ…Œ์ด๋ธ”๊ณผ point_users ํ…Œ์ด๋ธ”์˜ key๋Š” user_id์ด๋‹ค.
๋ชจ๋“  ์œ ์ €๊ฐ€ ํฌ์ธํŠธ๋ฅผ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, users ํ…Œ์ด๋ธ”์— ์žˆ๋Š” user_id๊ฐ€ point_users ํ…Œ์ด๋ธ”์—๋Š” ์—†์„ ์ˆ˜ ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ usersํ…Œ์ด๋ธ”๊ณผ point_user๋ฅผ left join์œผ๋กœ ํ•ฉ์นœ ๊ฒฐ๊ณผ ๋นˆ ๊ณต๊ฐ„์ด ์ƒ๊ธด๋‹ค.

 

์‚ฌ์šฉ ์˜ˆ์‹œ

  • user์ค‘์— ์ด๋ฆ„๋ณ„๋กœ  point๊ฐ€ ์—†๋Š” ์‚ฌ๋žŒ(์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ)๋“ค  ํ†ต๊ณ„
select 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 name

 

  • 7์›” 13์ผ ~ 16์ผ์— ๊ฐ€์ž…ํ•œ ๊ณ ๊ฐ ์ค‘, ํฌ์ธํŠธ๋ฅผ ๊ฐ€์ง„ ๊ณ ๊ฐ์˜ ์ˆซ์ž, ์ „์ฒด์ˆซ์ž, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋น„์œจ์„ ๋ณด๊ธฐ
select count(p.point_user_id) as pnt_user_cnt,
       count(*) as tot_user_cnt,
       round(count(p.point_user_id)/count(*),2) as ratio
 from users u
 left join point_users p on u.user_id = p.user_id
where u.created_at between '2020-07-13' and '2020-07-17'

 

๐Ÿ”ฅ Inner Join

๊ฐœ๋…

  • ๊ต์ง‘ํ•ฉ
  • ๋‘ ํ…Œ์ด๋ธ”์„ ํ•ฉ์น  ๋•Œ keyํ•„๋“œ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œํ…Œ์ด๋ธ”์—๋Š” ์žˆ๊ณ  ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์—๋Š” ์—†์„ ์ˆ˜ ์žˆ๋‹ค. inner join์€ ๋‘ ํ…Œ์ด๋ธ”์—์„œ ๋ชจ๋‘ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋งŒ ์ถœ๋ ฅํ•œ๋‹ค.
select * from users u
inner join point_users p
on u.user_id = p.user_id;

โ€ป ์ฟผ๋ฆฌ ์‹คํ–‰ ์ˆœ์„œ: from → join → select
1. from users u : usersํ…Œ์ด๋ธ”์—์„œ ๋ฐ์ดํ„ฐ ์ „์ฒด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
2. inner join point_users p on u.user_id = p.user_id : point_users๋ฅผ usersํ…Œ์ด๋ธ”์— ๋ถ™์ด๋Š”๋ฐ, usersํ…Œ์ด๋ธ”์˜ user_id์™€ ๋™์ผํ•œ user_id๋ฅผ ๊ฐ–๋Š” point_users์˜ ํ…Œ์ด๋ธ”์„ ๋ถ™์ธ๋‹ค.
3. select * : ๋ถ™์—ฌ์ง„ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

โ€ป from์— ๋“ค์–ด๊ฐ„ ํ…Œ์ด๋ธ” ๊ธฐ์ค€์œผ๋กœ, join ๋‹ค์Œ ํ…Œ์ด๋ธ”์ด ๋ถ™๋Š”๋‹ค
โ€ป join์˜ ์‹คํ–‰ ์ˆœ์„œ๋Š” ํ•ญ์ƒ from๊ณผ ๋ถ™์–ด๋‹ค๋‹Œ๋‹ค. (from → join)

 

์‚ฌ์šฉ์˜ˆ์‹œ

  • ๋„ค์ด๋ฒ„ ์ด๋ฉ”์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ์œ ์ €์˜ ์„ฑ์”จ๋ณ„ ์ฃผ๋ฌธ๊ฑด์ˆ˜ ์„ธ์–ด๋ณด๊ธฐ
select u.name, count(u.name) as count_name from orders o
inner join users u on o.user_id = u.user_id 
where u.email like '%naver.com'
group by u.name
์ฟผ๋ฆฌ ์‹คํ–‰ ์ˆœ์„œ: from → join → where → group by → select

 

  • ์›น๊ฐœ๋ฐœ, ์•ฑ๊ฐœ๋ฐœ ์ข…ํ•ฉ๋ฐ˜์˜ week๋ณ„ ์ฒดํฌ์ธ ์ˆ˜ ์„ธ๊ธฐ
select c2.title, c.week, count(*) from checkins c 
inner join courses c2 on c.course_id = c2.course_id 
group by c2.title, c.week
order by c2.title, c.week

โ€ป ์ฟผ๋ฆฌ ์‹คํ–‰ ์ˆœ์„œ: from → join → group by → order by → select
1. from checkins c: checkins ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ ์ „์ฒด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
2. inner join courses c2 on c.course_id = c2.course_id : checkinsํ…Œ์ด๋ธ”์˜ course_id์™€ ๋™์ผํ•œ course_id๋ฅผ ๊ฐ–๋Š” courses ํ…Œ์ด๋ธ”์„ ๋ถ™์ธ๋‹ค.
3. group by c2.title, c.week : coursesํ…Œ์ด๋ธ”์˜ ๊ฐ™์€ title๋ณ„๋กœ(์›น,์•ฑ๊ฐœ๋ฐœ ์ข…ํ•ฉ๋ฐ˜), checkinsํ…Œ์ด๋ธ”์˜ ๊ฐ™์€ week๋ณ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ•ฉ์ณ์ค€๋‹ค.
4. select c2.title, c.week, count(*) : (title), (week), (title, week๋ณ„๋กœ ๊ฐ๊ฐ ๋ช‡๊ฐœ๊ฐ€ ํ•ฉ์ณ์ง„ ๊ฒƒ์ธ์ง€ ์„ธ์–ด์ค€ ํ•„๋“œ)๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. 

 

๐Ÿ”ฅ Union

  • select ๋‘๊ฐœ๋กœ ์ด๋ฃจ์–ด์ง„ ํ…Œ์ด๋ธ”์„ ํ•ฉ์นœ๋‹ค.
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

 

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

 

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

ํ•˜์ง€๋งŒ union์—์„  ๋‚ด๋ถ€ ์ •๋ ฌ์ด ์•ˆ ๋จน๋Š”๋‹ค.
SubQuery๋ฅผ ์‚ฌ์šฉํ•˜์ž!

 


Source

์ŠคํŒŒ๋ฅดํƒ€ ์ฝ”๋”ฉํด๋Ÿฝ ๋‚ด์ผ๋ฐฐ์›€๋‹จ ์—‘์…€๋ณด๋‹จ ์‰ฌ์šด SQL 3์ฃผ์ฐจ