ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด/SQL

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

ใ‚ใกใ‚ƒใใกใ‚ƒ ้–‹็™บ่€…๐Ÿฆพ 2022. 6. 14. 23:58

ใ€Š ์ŠคํŒŒ๋ฅดํƒ€์ฝ”๋”ฉํด๋Ÿฝ SQL โ€•1์ฃผ์ฐจโ€• ใ€‹

ใ€Š ์ŠคํŒŒ๋ฅดํƒ€์ฝ”๋”ฉํด๋Ÿฝ SQL  โ€•2์ฃผ์ฐจโ€• ใ€‹


 

[ JOIN ๋ฌธ ]

 - JOIN๋ฌธ ์ด๋ž€ ๋น„๊ตํ•  ๋‘ ํ…Œ์ด๋ธ”์˜ ๊ณตํ†ต๋œ ์ •๋ณด(key๊ฐ’)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•˜์—ฌ ํ•œ ํ…Œ์ด๋ธ”์ฒ˜๋Ÿผ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒํ•˜๋Š” ๊ตฌ๋ฌธ์ž„

 - ์—‘์…€์˜ VLOOKUP ํ•จ์ˆ˜์™€ ์œ ์‚ฌํ•จ

 

 

[ JOIN๋ฌธ ์˜ˆ์‹œ ]

์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์€ ๋‘ ํ…Œ์ด๋ธ”์„ ๋ณด๋ฉด ๊ณตํ†ต์ ์œผ๋กœ user_id๋ผ๋Š” ํ‚ค๊ฐ’์„ ๊ฐ€์ง„ ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Œ

(์ขŒ) users ํ…Œ์ด๋ธ”      (์šฐ) point_users ํ…Œ์ด๋ธ”

์ด๋Ÿด ๋•Œ user_id๋ฅผ ๊ธฐ์ค€์œผ๋กœ JOIN๋ฌธ์„ ํ†ตํ•ด ํ•œ๊ฐœ์˜ ํ…Œ์ด๋ธ”์ฒ˜๋Ÿผ ๋ฌถ์–ด์„œ ๋ณผ ์ˆ˜ ์žˆ์Œ

 

# ๊ธฐ๋ณธ ๋ฌธ๋ฒ•
select <select_list> from Table_A A 
  left join Table_B B on A.key(๊ณตํ†ตํ‚ค) = B.key(๊ณตํ†ตํ‚ค)

# user_id๋ฅผ ๊ธฐ์ค€์œผ๋กœ users ํ…Œ์ด๋ธ”๊ณผ point_users ํ…Œ์ด๋ธ”์„ ํ•ฉ์น˜๊ธฐ [ LEFT JOIN ]
select * from users u 
  left join point_users p on u.user_id = p.user_id
  
# user_id๋ฅผ ๊ธฐ์ค€์œผ๋กœ users ํ…Œ์ด๋ธ”๊ณผ point_users ํ…Œ์ด๋ธ”์„ ํ•ฉ์น˜๊ธฐ [ INNER JOIN ]
select * from users u
  inner join point_users p on u.user_id = p.user_id

LEFT JOIN๋ฌธ์œผ๋กœ ๋ณ‘ํ•ฉ๋œ ํ…Œ์ด๋ธ”
INNER JOIN๋ฌธ์œผ๋กœ ๋ณ‘ํ•ฉ๋œ ํ…Œ์ด๋ธ”

ํ™•์ธ์„ ํ•ด๋ณด๋ฉด LEFT JOIN๋ฌธ์„ ํ†ตํ•ด user_id๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ด๋ธ”์„ ๋ณ‘ํ•ฉํ•œ ๊ฒฐ๊ณผ ํ…Œ์ด๋ธ”์€ ํ•ฉ์ณ์กŒ์ง€๋งŒ, 

์ด์ค‘ ์–ด๋–ค ํ•„๋“œ๋Š” NULL๊ฐ’์œผ๋กœ ํ‘œํ˜„๋œ ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Œ

 

 

 

[ LEFT JOIN๋ฌธ ]

 - LEFT JOIN๋ฌธ์€ ์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ”(ํ…Œ์ด๋ธ” B)์— ์ผ์น˜ํ•˜๋Š” ํ•„๋“œ๊ฐ€ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ์™ผ์ชฝ ํ…Œ์ด๋ธ”(ํ…Œ์ด๋ธ” A)์—

   ์žˆ๋Š” ๋ชจ๋“  ํ•„๋“œ๋ฅผ ๋ฐ˜ํ™˜, ๋˜ํ•œ ์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ”์—์„œ ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ ๋˜ํ•œ ๋ฐ˜ํ™˜

 - ์ฆ‰ ํ…Œ์ด๋ธ” A์™€ ํ…Œ์ด๋ธ” B์˜ ๋ชจ๋“  ํ•„๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ํ•„๋“œ๋Š” ์ผ๋ถ€ NULL๊ฐ’์œผ๋กœ ํ‘œ์‹œ๋จ 

LEFT JOIN ๊ด€๊ณ„๋„

 

[ INNER JOIN๋ฌธ ]

 - INNER JOIN๋ฌธ์€ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ณ  ์ง๊ด€์ ์ธ JOIN๋ฌธ์˜ ํ•˜๋‚˜๋กœ์„œ ์™ผ์ชฝ ํ…Œ์ด๋ธ”(ํ…Œ์ด๋ธ” A)์™€ ์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ”(ํ…Œ์ด๋ธ” A)

   ๋ชจ๋‘ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ•„๋“œ๋ฅผ ๋ฐ˜ํ™˜

 - ์ฆ‰ ๋‘ ํ…Œ์ด๋ธ”์˜ ๊ต์ง‘ํ•ฉ์ด ๋˜๋Š” ํ•„๋“œ๋ฅผ ๋ฐ˜ํ™˜, ๋น„์–ด์žˆ๋Š” ํ•„๋“œ ๋ฐ์ดํ„ฐ ์กด์žฌํ•˜์ง€ ์•Š์Œ

INNER JOIN ๊ด€๊ณ„๋„

 

์ด๋ฏธ์ง€ ์ถœ์ฒ˜ : https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins 

 

[ UNION & UNION ALL ]

 - UNION์€ ๋‘๊ฐœ์˜ ์ฟผ๋ฆฌ๋ฌธ์„ ๋‹จ์ผ ๊ฒฐ๊ณผ ์„ธํŠธ๋กœ ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๋Š” ์—ญํ• ์„ ํ•จ

 - UNION์€ ๋‘ ๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ ๊ฒฐํ•ฉํ•œ๋‹ค๊ณ  ๊ฐ€์ • ์‹œ ์ค‘๋ณต ํ•ญ๋ชฉ์„ ์ œ์™ธํ•˜๊ณ  ํ‘œ์ถœ

 - UNION ALL์€ ์ค‘๋ณต ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•˜์ง€ ์•Š์€ ์ฑ„ ํ‘œ์ถœ

 - ๋งŒ์•ฝ ์ค‘๋ณต ์ฒดํฌํ•  ๋ฐ์ดํ„ฐ์˜ ์–‘์ด ๋งŽ์„ ๊ฒฝ์šฐ UNION์˜ ๊ฒฝ์šฐ ๋งŽ์€ ๋ถ€ํ•˜๋ฅผ ์ค„ ์ˆ˜ ์žˆ์–ด ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ž˜ ์‚ฌ์šฉํ•ด์•ผ ํ•จ

 - UNION ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ ์‹œ ์—ด์˜ ๊ฐœ์ˆ˜์™€ ์ˆœ์„œ๊ฐ€ ๋ชจ๋“  ์ฟผ๋ฆฌ์—์„œ ๋™์ผํ•ด์•ผ ํ•จ

 - ๋ฐ์ดํ„ฐ ํ˜•์‹์ด ํ˜ธํ™˜๋˜์–ด์•ผ ํ•จ

# ๊ธฐ๋ณธ ๋ฌธ๋ฒ• (๋‹จ์ˆœ UNION ์‚ฌ์šฉ)
select <select_list> from Table_A
UNION(UNION ALL)
select <select_list> from Table_B

์ถœ์ฒ˜ :&nbsp;https://velog.io/@superahxd/SQL-Union-Union-all-Intersect-semijoin-antijoin

 

 

 

 

[ INNER JOIN ์˜ˆ์ œ ]

โ‘  ๊ฒฐ์ œ ์ˆ˜๋‹จ๋ณ„ ์œ ์ € ํฌ์ธํŠธ์˜ ํ‰๊ท ๊ฐ’ ๊ตฌํ•ด๋ณด๊ธฐ

select o.payment_method, 
       round(avg(pu.`point`)) as 'ํฌ์ธํŠธ ํ‰๊ท ๊ฐ’'
  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 '๋ฏธ์ˆ˜๊ฐ• ์œ ์ € ์ˆ˜' 
  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 count(*) desc;

 

 

โ‘ข ๊ณผ๋ชฉ๋ณ„ ์ˆ˜๊ฐ•์„ ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ์œ ์ € ์ˆ˜๋ฅผ ํ™•์ธํ•˜๊ธฐ

select c.course_id, 
       c.title,
       count(*) as '๊ณผ๋ชฉ๋ณ„ ๋ฏธ์ˆ˜๊ฐ• ์œ ์ € ์ˆ˜'
  from courses c
  inner join enrolleds e on c.course_id  = e.course_id 
  where e.is_registered = 0
  group by c.title;

 

 

โ‘ฃ ์›น๊ฐœ๋ฐœ, ์•ฑ๊ฐœ๋ฐœ ์ข…ํ•ฉ๋ฐ˜์˜ week๋ณ„ ์ฒดํฌ์ธ ์ˆ˜ ์„ธ์–ด๋ณด๊ธฐ

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

 

 

โ‘ค ์˜ˆ์ œโ‘ฃ์—์„œ 8์›” 1์ผ ์ดํ›„ ๊ตฌ๋งคํ•œ ๊ณ ๊ฐ๋“ค๋งŒ ์ถœ๋ ฅ(๋‘๊ฐœ ์ด์ƒ ํ…Œ์ด๋ธ” JOIN)

select c.title,
       ch.week,
       count(*) as cnt 
  from courses c
  inner join checkins ch on c.course_id = ch.course_id
  inner join orders o on ch.user_id  = o.user_id
  where o.created_at >= '2020-08-01'
  group by c.title, ch.week
  order by c.title, ch.week;

 

 

 

 

 

[ 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 NOT NULL 
  group by u.name
  order by count(*) desc;

 

 

โ‘ก 7์›” 10์ผ ~ 7์›” 19์ผ์— ๊ฐ€์ž…ํ•œ ๊ณ ๊ฐ ์ค‘ ํฌ์ธํŠธ๋ฅผ ๊ฐ€์ง„ ๊ณ ๊ฐ์˜ ์ˆ˜, ์ „์ฒด ์ˆ˜, ๋น„์œจ ํƒ์ƒ‰

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

 

 

 

 

[ UNION ์—ฐ์‚ฐ ์˜ˆ์ œ ]

โ‘  7์›” ์ˆ˜๊ฐ• ๊ณผ๋ชฉ/์ฃผ์ฐจ๋ณ„ ์ธ์› ์ˆ˜ ์ฟผ๋ฆฌ๋ฌธ๊ณผ 8์›” ์ˆ˜๊ฐ• ๊ณผ๋ชฉ/์ฃผ์ฐจ๋ณ„ ์ธ์› ์ˆ˜ ์ฟผ๋ฆฌ๋ฌธ ๊ฒฐํ•ฉ

(
	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 ์—ฐ์‚ฐํ•  ๊ฒฝ์šฐ ์ •๋ ฌ์„ ๋งˆ์ง€๋ง‰ ์ฟผ๋ฆฌ๋ฌธ์—์„œ ์‹œํ–‰
	  # 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
);

 

 

 

[ ๐ŸŒ” 3์ฃผ์ฐจ ์†Œ๊ฐ ]

3์ฃผ์ฐจ์—๋Š” JOIN๋ฌธ๊ณผ UNION ํ•จ์ˆ˜์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ดค๋Š”๋ฐ ํ™•์‹คํžˆ JOIN๋ฌธ์€ ๊ต‰์žฅํžˆ ๋งŽ์ด ์‚ฌ์šฉ๋  ๊ฒƒ ๊ฐ™๋‹ค.

๋˜ํ•œ JOIN๋ฌธ์— ๋Œ€ํ•ด ์กฐ๊ธˆ ๋” ๊ฒ€์ƒ‰ํ•ด๋ณด๋‹ˆ EQUI JOIN๊ณผ์˜ ๊ฒฐ๊ณผ๋Š” ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์ง€๋งŒ,

์ถ”ํ›„ ๋‹ค๋ฅธ ์ƒํ™ฉ๋“ค์„ ๋Œ€๋น„ํ–ˆ์„๋•Œ INNER JOIN๋ฌธ์ด ๋” ์ข‹๊ธฐ ๋•Œ๋ฌธ์— INNER JOIN๋ฌธ๊ณผ LEFT JOIN๋ฌธ์„

ํ•ด๋‹น ๊ฐ•์˜์—์„œ ์•ˆ๋‚ดํ•œ ๊ฒƒ์ด ์•„๋‹๊นŒ ๋‚˜๋ฆ„๋Œ€๋กœ ์ถ”์ธก์„ ํ•ด๋ณด์•˜๋”ฐ.

์ด์ œ ๋งˆ์ง€๋ง‰ 1์ฃผ๊ฐ€ ๋‚จ์•˜์œผ๋‹ˆ ๋๊นŒ์ง€ ์ง‘์ค‘ํ•ด์„œ ๊ณ ๊ณ