[MySQL] JOIN

ํ˜ธ๋นตยท2024๋…„ 7์›” 24์ผ

SQL_์ด๋ก 

๋ชฉ๋ก ๋ณด๊ธฐ
3/5

๐Ÿ“… ๊ณต๋ถ€ ๊ธฐ๊ฐ„ : 07. 24(์ˆ˜)

๋‘ ๊ฐœ์˜ ํ…Œ์ด๋ธ”(๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑ๋˜์–ด ์žˆ๋Š” ํ…Œ์ด๋ธ”)๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒ
๐Ÿ’ก ๋‘ ํ…Œ์ด๋ธ”์€ PK(Primary Key), FK(Foreign Key)๊ฐ€ ์žˆ์–ด์•ผ ํ•จ

์˜ˆ์ œ ๋‹ค์ด์–ด๊ทธ๋žจ ๊ฐœ์š”

CROSS JOIN

์ž˜ ์“ฐ์ง€๋Š” ์•Š์Œ

  • ํฌ๋กœ์Šค ์กฐ์ธ (= ์นด๋ฅดํ…Œ์‹œ์•ˆ ์กฐ์ธ)
  • A x B
-- hr.employees e : ์ฒซ ๋ฒˆ์งธ ์ง‘ํ•ฉ, hr.departments d : ๋‘ ๋ฒˆ์งธ ์ง‘ํ•ฉ
SELECT *
FROM hr.employees e CROSS JOIN hr.departments d ;

-- CROSS JOIN ์ƒ๋žต ๊ฐ€๋Šฅ
SELECT *
FROM hr.employees e, hr.departments d ; 

INNER JOIN

  • ์„œ๋กœ ๊ด€๊ณ„๋ฅผ ๋งบ๊ณ  ์žˆ๋Š” ๋‘˜ ์ด์ƒ์˜ ํ…Œ์ด๋ธ”๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒ
  • INNER ์ƒ๋žตํ•˜๊ณ  JOIN๋งŒ ์จ๋„ ๋จ
  • FK ๊ฐ’์ด NULL์ธ ๊ฒฝ์šฐ์—๋Š” ์กฐํšŒ๋Œ€์ƒ์—์„œ ์ œ์™ธ
SELECT *
FROM hr.employees e INNER JOIN hr.departments d 
ON e.department_id = d.department_id ;
/* ON์ ˆ์€ USING์ ˆ๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅ
USING (department_id);
*/

OUTER JOIN

  • INNER JOIN๊ณผ๋Š” ๋‹ฌ๋ฆฌ FK ๊ฐ’์ด NULL์ธ ๊ฒฝ์šฐ๋„ ์กฐํšŒ
    (๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค ์กฐํšŒ)

LEFT OUTER JOIN

  • OUTER ์ƒ๋žตํ•˜๊ณ  LEFT JOIN๋งŒ ์จ๋„ ๋จ
  • NULL์„ ๊ฐ€์ง„ ํ…Œ์ด๋ธ”, ์ฆ‰ ์ž์‹ ํ…Œ์ด๋ธ”(์ถœ๋ ฅํ•˜๊ณ  ์‹ถ์€ ํ…Œ์ด๋ธ”)์„ ์™ผ์ชฝ์— ๋ฐฐ์น˜
-- [๋ฌธ์ œ] ์ „ ์ง์›์˜ ์ด๋ฆ„, ๊ธ‰์—ฌ, ๋ถ€์„œ๋ช…์„ ์กฐํšŒํ•˜์‹œ์˜ค
-- employees ํ…Œ์ด๋ธ”์ด ์ž์‹, departments ํ…Œ์ด๋ธ”์ด ๋ถ€๋ชจ
SELECT e.first_name, e.salary, e.department_id 
FROM hr.employees e 
LEFT OUTER JOIN hr.departments d 
ON e.department_id = d.department_id;

RIGHT OUTER JOIN

  • OUTER ์ƒ๋žตํ•˜๊ณ  RIGHT JOIN๋งŒ ์จ๋„ ๋จ
  • NULL์„ ๊ฐ€์ง„ ํ…Œ์ด๋ธ”, ์ฆ‰ ์ž์‹ ํ…Œ์ด๋ธ”(์ถœ๋ ฅํ•˜๊ณ  ์‹ถ์€ ํ…Œ์ด๋ธ”)์„ ์˜ค๋ฅธ์ชฝ์— ๋ฐฐ์น˜
-- [๋ฌธ์ œ] ๋ถ€์„œ๋ช…๊ณผ ๋ถ€์„œ๊ฐ€ ์œ„์น˜ํ•œ ๋„์‹œ์™€ ํ•ด๋‹น ๋„์‹œ๊ฐ€ ์žˆ๋Š” ๋‚˜๋ผ๋ฅผ ์กฐํšŒํ•˜์‹œ์˜ค
--- 1) locations ํ…Œ์ด๋ธ”์ด ์ž์‹, countries ํ…Œ์ด๋ธ”์ด ๋ถ€๋ชจ
--- 2) departments ํ…Œ์ด๋ธ”์ด ์ž์‹, locations ํ…Œ์ด๋ธ”์ด ๋ถ€๋ชจ
SELECT d.department_name , l.city, c.country_name
FROM hr.countries c RIGHT OUTER JOIN hr.locations l 
ON c.country_id = l.country_id
RIGHT OUTER JOIN hr.departments d 
ON l.location_id = d.location_id ;

SELF JOIN

  • ํ•˜๋‚˜์˜ ํ…Œ์ด๋ธ”์— PK์™€ FK๋ฅผ ๊ฐ™์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ
  • USING์ ˆ์„ ์“ฐ๊ธฐ ์–ด๋ ค์›€

    ์ž์‹์˜ FK <= ๋ถ€๋ชจ์˜ PK๊ฐ€ ์ „์ด

-- [๋ฌธ์ œ] ์‚ฌ์› ๋ฒˆํ˜ธ์™€ ์ด๋ฆ„, ์ƒ๊ด€์˜ ์‚ฌ์› ๋ฒˆํ˜ธ์™€ ์ƒ๊ด€์˜ ์ด๋ฆ„์„ ์กฐํšŒํ•˜์‹œ์˜ค
SELECT e1.employee_id, e1.first_name AS "์ง์›๋ช…", e2.employee_id, e2.first_name AS "๋งค๋‹ˆ์ €๋ช…"
FROM hr.employees e1 /* ์ž์‹์„ ์™ผ์ชฝ์— FK */
INNER JOIN hr.employees e2 /* ๋ถ€๋ชจ๋ฅผ ์˜ค๋ฅธ์ชฝ์— PK */ 
ON e1.manager_id = e2.employee_id ; -- ์ž์‹์˜ FK์™€ ๋ถ€๋ชจ์˜ PK

-- [๋ฌธ์ œ] ์œ„ ๋ฌธ์ œ์—์„œ Steven(์‚ฌ์žฅ, ์ƒ๊ด€์ด ์—†์Œ)๋„ ์ถœ๋ ฅ๋˜๋„๋ก ํ•˜์‹œ์˜ค
-- left outer join
SELECT e1.employee_id, e1.first_name AS "์ง์›๋ช…", e2.employee_id, e2.first_name AS "๋งค๋‹ˆ์ €๋ช…"
FROM hr.employees e1 /* ์ž์‹์„ ์™ผ์ชฝ์— FK */
LEFT JOIN hr.employees e2 /* ๋ถ€๋ชจ๋ฅผ ์˜ค๋ฅธ์ชฝ์— PK */ 
ON e1.manager_id = e2.employee_id ; -- ์ž์‹์˜ FK์™€ ๋ถ€๋ชจ์˜ PK

๐Ÿ’ก key point : Steven์€ ์‚ฌ์žฅ์ด๋ผ ์ƒ๊ด€(๋งค๋‹ˆ์ €)์ด ์—†์–ด์„œ e1.manager_id๊ฐ€ NULL ๊ฐ’. ๋”ฐ๋ผ์„œ Steven์„ ํ•จ๊ป˜ ์กฐํšŒํ•˜๋ ค๋ฉด FK๊ฐ€ NULL ๊ฐ’์ด๋ฉด ์กฐํšŒํ•˜์ง€ ์•Š๋Š” INNER JOIN ๋Œ€์‹  FK๊ฐ€ NULL ๊ฐ’์ด์–ด๋„ ์กฐํšŒํ•˜๋Š” OUTER JOIN์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ

profile
์ธ๋ฅ˜์˜ ์œ„๋Œ€ํ•œ ๋Œ€ํ™”์— ์ฐธ์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์–‘ํ•œ ์–ธ์–ด๋ฅผ ํƒ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

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