Join์ด๋?
JOIN์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ด์ ์ฌ๋ฌ ํ ์ด๋ธ์์ ๊ฐ์ ธ์จ ๋ ์ฝ๋๋ฅผ ์กฐํฉํ์ฌ ํ๋์ ํ ์ด๋ธ์ด๋ ๊ฒฐ๊ณผ ์งํฉ์ผ๋ก ํํํด ์ค๋ค. ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์๋ ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๊ธฐ๋ฅ์ผ๋ก, ์งํฉ์ ๊ฐ๋ ์ผ๋ก ์ดํดํ๊ณ ๋ณด๋ฉด ์ฝ๋ค

INNER JOIN
์กฐ์ธํ๋ ํ
์ด๋ธ์ ON์ ์ ์กฐ๊ฑด์ด ์ผ์นํ๋ ๊ฒฐ๊ณผ๋ง ์ถ๋ ฅํ๋ค.
๊ต์งํฉ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ํธํ๋ค
mysql์์๋ JOIN, INNER JOIN, CROSS JOIN์ด ๊ฐ์ ์๋ฏธ๋ก ์ฌ์ฉ ๋๋ค
๊ธฐ๋ณธ ๊ตฌ๋ฌธ
select a.userid, name
from users as a inner join history as b
on a.userid = b.userid
where a.userid = "1"๋ ๊ฐ์ ํ ์ด๋ธ์ ๋น๊ตํ ๋๋ ๊ฐ ํ ์ด๋ธ์ ์๋ณํ๋ ๋ณ์? ๋ฅผ as๋ก ์ง์ ํ ๋ค์ ์กฐ์ธ์ ํ ๋ ์ ๊ทผ์๋ฅผ ํตํด์ ๊ฐ ํ ์ด๋ธ์ ์๋ณํ ์ ์๋๋ก ํ๋ค!
ํจ์ถ ๊ตฌ๋ฌธ
select a.userid, name
from users a, history b
where a.userid = b.userid and a.userid ="1"LEFT/RIGHT OUTER JOIN
๋ ํ
์ด๋ธ์ด ํฉ์ณ์ง ๋ ์ผ์ชฝ/์ค๋ฅธ์ชฝ์ ๊ธฐ์ค์ผ๋ก ๋ฐฉํฅ์ ์ ํ๊ณ , ์ ํ ๋ฐฉํฅ์ ์ปฌ๋ผ์ ๋ชจ๋ ๊ฐ์ ธ์จ๋ค
ํ๋ง๋๋ก on ์กฐ๊ฑด์์ ์ค์ ํ ์กฐ๊ฑด์์ ํ ๋ฐฉํฅ์ ๋ฐ์ดํฐ๋ฅผ ๋ค ๊ฐ์ ธ์จ๋ค๋ ์๋ฆฌ๋ค
OUTER JOIN์ LEFT/RIGHT OUTER JOIN, FULL OUTER JOIN์ด ์๋ค.
๋๋ถ๋ถ LEFT OUTER JOIN์ ๋ง์ด ์ฌ์ฉํ๋๋ฐ, ์ผ์ชฝ์ ๋ฐฉํฅ์ผ๋ก ์ก๋ ์ด์ ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋ ๊ตฌ์กฐ ๋ฑ์ ์ฐ๊ด์ด ์๋ค.
์ฒ์์ ์กฐ์ธํ ๋ ์ธ ํ ์ด๋ธ์ ์ผ์ชฝ์ ๋๊ณ LEFT JOINํ๋ ๋ฐฉ์์ผ๋ก ํ๊ฒ ๋๋ฉด ๋ฐ์ดํฐ ๋ํ ์ผ์ชฝ โ ์ค๋ฅธ์ชฝ์ผ๋ก ์์ธ์คํ๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ์ ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ๊ธ์ ์ฝ๋ ๋ฐฉ์์ฒ๋ผ ์ โ ์๋์ ์์๋๋ก ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ณด๋ค ์ผ๋ฐ์ ์ธ ๋ฐฉ์์ผ๋ก LEFT JOIN์ ์ฌ์ฉํ์ฌ ๊ฐ์ฅ ๋ง์ ์ด์ ๊ฐ์ ธ์์ผ ํ ํ ์ด๋ธ์ ์ผ์ชฝ์ ์ฐ์ ์ ์ผ๋ก ์ ์ด์ค๋ค
๊ธฐ๋ณธ ๊ตฌ๋ฌธ(LEFT JOIN)
-- ์) 1ํ๋
ํ์์ ์ด๋ฆ๊ณผ ์ง๋๊ต์๋ช
์ ์ถ๋ ฅํ๋ผ. ๋จ, ์ง๋๊ต์๊ฐ ์ง์ ๋์ง ์์ ํ์๋ ์ถ๋ ฅ๋๊ฒ ํ๋ผ.
SELECT STUDENT.NAME, PROFESSOR.NAME
FROM STUDENT LEFT OUTER JOIN PROFESSOR -- STUDENT๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ ์กฐ์ธ
ON STUDENT.PID = PROFESSOR.ID
WHERE GRADE = 1๊ธฐ๋ณธ ๊ตฌ๋ฌธ(RIGHT JOIN)
-- ์) 1ํ๋
ํ์์ ์ด๋ฆ๊ณผ ์ง๋๊ต์๋ช
์ ์ถ๋ ฅํ๋ผ. ๋จ, ์ง๋๊ต์๊ฐ ์ง์ ๋์ง ์์ ํ์๋ ์ถ๋ ฅ๋๊ฒ ํ๋ผ.
SELECT STUDENT.NAME, PROFESSOR.NAME
FROM STUDENT RIGHT OUTER JOIN PROFESSOR -- PROFESSOR๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ฅธ์ชฝ ์กฐ์ธ
ON STUDENT.PID = PROFESSOR.ID
WHERE GRADE = 13์ค ์กฐ์ธ
3๊ฐ์ ํ ์ด๋ธ์ ์กฐํฉํด์ผ ํ ๋๋ outer join์ ์ฐ์์ผ๋ก 3๋ฒ ์ฌ์ฉํ๋ฉด ๋๋ค.
-- 3๊ฐ์ ํ
์ด๋ธ์ joinํ๊ณ ํ๊ตญ์๋ํ ์ ๋ณด๋ง ๋ทฐ๋ก ์์ฑํด๋ผ
create view allView as
(
select A.Name, A.CountryCode
from city A
left join country B
on A.countrycode = B.code -- ํ
์ด๋ธ 2๊ฐ ์กฐ์ธ ์๋ฃ
left join countrylanguage C
on B.code = C.countrycode -- ํ
์ด๋ธ 3๊ฐ ์กฐ์ธ ์๋ฃ
where A.countrycode in ('KOR');
)FULL OUTER JOIN

full outer join์ ๋ ํ
์ด๋ธ์ ํฉ์งํฉ์ด๋ค.
ํ์ง๋ง full outer join๊ฐ์ ๊ฒฝ์ฐ ๋๋ถ๋ถ db๊ฐ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ Union์ ํ์ฉํ์ฌ ๊ฐ์ ์ ์ผ๋ก ๊ตฌํํ๋ค.
-- full outer join
select *
from topic FULL OUTER JOIN autor
on topic.auther_id = authoer.id
-- ๊ฐ์๊ตฌ๋ฌธ
(select * from topic LEFT JOIN autor on topic.auther_id = authoer.id))
UNION
(select * from topic RIGHT JOIN autor on topic.auther_id = authoer.id))UNION
UNION์ ์ฌ๋ฌ ๊ฐ์ SELECT๋ฌธ์ ๊ฒฐ๊ณผ๋ฅผ ํ๋์ ํ ์ด๋ธ์ด๋ ๊ฒฐ๊ณผ ์งํฉ์ผ๋ก ํํํ ๋ ์ฌ์ฉํ๋ค.
โ ๏ธ ์ด ๋ ๊ฐ๊ฐ์ SELECT๋ฌธ์ผ๋ก ์ ํ๋ ํ๋์ ๊ฐ์์ ํ์ ์ ๋ชจ๋ ๊ฐ์์ผ ํ๋ฉฐ, ํ๋์ ์์ ๋ํ ๊ฐ์์ผ ํ๋ค. โ ๏ธ ๊ธฐ๋ณธ ์งํฉ ์ฟผ๋ฆฌ์๋ ์ค๋ณต ์ ๊ฑฐ๊ฐ ์๋ ํฌํจ๋์ด ์๋ค.
SELECT ํ๋์ด๋ฆ FROM ํ
์ด๋ธ์ด๋ฆ
UNION
SELECT ํ๋์ด๋ฆ FROM ํ
์ด๋ธ์ด๋ฆUNION ALL
UNION์ DISTINCT ์๋ ํฌํจ์ด๋ผ ์ค๋ณต๋๋ ๋ ์ฝ๋๋ฅผ ์ ๊ฑฐํ๊ธฐ ๋๋ฌธ์, ์ค๋ณต๋๋ ๋ ์ฝ๋๊น์ง ๋ชจ๋ ์ถ๋ ฅํ๊ณ ์ถ๋ค๋ฉด ALL ํค์๋๋ฅผ ๋ถ์ด๋ฉด ๋๋ค.
SELECT ํ๋์ด๋ฆ FROM ํ
์ด๋ธ์ด๋ฆ
UNION ALL
SELECT ํ๋์ด๋ฆ FROM ํ
์ด๋ธ์ด๋ฆEXCLUSIVE JOIN

EXCLUSIVE LEFT JOIN์ A์ ์ฌ์งํฉ๊ณผ ๊ฐ์ ๋๋์ด๋ค. ์กฐ๊ฑด์ ํด๋นํ๋ ๊ฒ์ ์ ์ธํ๊ณ ํน์ ํ ์ด๋ธ์ ์๋ ๋ ์ฝ๋๋ง ๊ฐ์ ธ์จ๋ค. EXCLUSIVE JOIN๋ LEFT/RIGHT๊ฐ ๋๋์ด์ ธ ์๋๋ฐ, ๋ฐฉํฅ์ ๋ฐ๋ผ ํ์ชฝ์ ๋ฐ์ดํฐ๋ง ๊ฐ์ ธ์จ๋ค
SELECT *
FROM table1 A LEFT JOIN table2 B
ON A.ID_SEQ = B.ID_SEQ
WHERE B.ID_SEQ IS NULL -- ์กฐ์ธํ B ํ
์ด๋ธ์ ๊ฐ์ด null๋ง ์ถ๋ ฅํ๋ผ๋ ๋ง์, ์กฐ์ธ์ด ์๋ A ๋ ์ฝ๋ ๋๋จธ์ง๊ฐ๋ง ์ถ๋ ฅํ๋ผ๋ ๋งSELF JOIN
์์ฒด ์กฐ์ธ(SELF JOIN)์ ํ
์ด๋ธ ์๊ธฐ ์์ ์ ์กฐ์ธํ๋ ๊ฒ์ด๋ค.

SELECT E.NAME as Name, M.NAME as Secret_Santa
FROM Santa E, Santa M -- inner join
WHERE E.Santa_Color = M.Color;DRIVING TABLE
JOIN์ ๋จผ์ ์์ธ์ค๋ผ์ ACCESS PATH๋ฅผ ์ฃผ๋ํ๋ ํ ์ด๋ธ ์ด๋์ ๋ฐ์ดํฐ๋ถํฐ ์ถ๋ฐํด์ ๊ฐ์ ์ฐพ๋๋์ ๋ฐ๋ผ ์ฑ๋ฅ์ ์ข์ง์ฐ์งํ๋ค.
๋ํ์ ์ธ ์๋ก
- (์กฐ๊ฑด์ ๋ง์กฑํ๋)5000๋ง๊ฑด์ ๋ฐ์ดํฐ A ํ ์ด๋ธ
- (์กฐ๊ฑด์ ๋ง์กฑํ๋)1000๊ฑด์ ๋ฐ์ดํฐ B ํ ์ด๋ธ
์ด ๋๊ฐ๊ฐ ์์ ๋ ์กฐ์ธ ๊ณผ์ ์์ Aํ ์ด๋ธ์ ๋จผ์ ์์ธ์คํ๋ฉด 5000๋ง๋ฒ์ ํ์ํ๊ณ Bํ ์ด๋ธ์ ์์ธ์คํ๋ฉด 1000๋ฒ์ ์์ธ์ค๋ง์ผ๋ก ํ์์ด ์๋ฃ๋๋ค๋ ์ฐจ์ด๋ฅผ ๋ ๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์กฐ์ธ์ ํ ๋ ๋ณด๋ค ์ ์ ๋ฐ์ดํฐ์ ์์ด ๋ค์ด๊ฐ ํ๋ฅ ์ด ๋์ ํ ์ด๋ธ์ ๋ํด์ ๋๋ผ์ด๋น ํ ์ด๋ธ๋ก ์ค์ ํด์ผ ํ ํ์์ฑ์ด ์๋ค.(๋ฌผ๋ก ๊ด๊ณ๋ ๊ณ ๋ คํด์ผ๊ฒ ์ง๋ง)
DRIVING TABLE์ ๊ฒฐ์ ๊ท์น
๊ท์น ๊ธฐ๋ฐ ์ตํฐ๋ง์ด์ (Rule-Based Optimizer)์์๋ ์ฐ์ฐ์, ์ธ๋ฑ์ค ์ ๋ฌด, ์กฐ๊ฑด์ ํํ ๋ฑ ์ ํด์ง ๊ท์น์ ์ฐ์ ์์์ ๋ฐ๋ผ ์คํ ๊ณํ์ ์์ฑํ๋ค.
- ๏ปฟ๏ปฟ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ ์ก์ธ์ค ๋ฐฉ์์ด ์ ์ฒด ํ ์ด๋ธ ์ก์ธ์ค ๋ฐฉ์๋ณด๋ค ์ฐ์ ์์๊ฐ ๋์
- ๏ปฟ๏ปฟ์กฐ์ธ ์นผ๋ผ์ ๋ํ ์ธ๋ฑ์ค๊ฐ ์์ชฝ ํ ์ด๋ธ์ ๋ชจ๋ ์กด์ฌํ ๋, ์ฐ์ ์์๊ฐ ๋์ ํ ์ด๋ธ์ ์ ํ
- ๏ปฟ๏ปฟ์กฐ์ธ ์นผ๋ผ์๋ง ์ธ๋ฑ์ค๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋ ์ธ๋ฑ์ค๊ฐ ์๋ ํ ์ด๋ธ์ ๋จผ์ ์ ํํ์ฌ ์กฐ์ธ ์ํ
- ๏ปฟ๏ปฟ๋ง์ฝ ์กฐ์ธ ํ ์ด๋ธ์ ์ฐ์ ์์๊ฐ ๋์ผํ์ง์๋ค๋ฉด, FROM ์ ์ ๋์ด๋ ํ ์ด๋ธ์ ์ญ์์ผ๋ก ์ํ
ํ์ง๋ง ์ต๊ทผ์๋ ๋น์ฉ๊ธฐ๋ฐ ์ตํฐ๋ง์ด์ (Cost-Based Optimizer)๋ฅผ ์ฑํํ๋ค. ๋น์ฉ๊ธฐ๋ฐ ์ตํฐ๋ง์ด์ ๋ ์ฟผ๋ฆฌ๋ฅผ ์ํํ๋๋ฐ ์์๋๋ ์์ ๋น์ฉ์ ๋ฐํ์ผ๋ก ์คํ ๊ณํ์ ์์ฑํ๋ค.
์คํ ๊ณํ์ ์ธ๋ฑ์ค๋ฅผ ๊ธฐ์ค์ผ๋ก ๋๋๋ค. ์ธ๋ฑ์ค๊ฐ ์์ ๊ฒฝ์ฐ ์ธ๋ฑ์ค๊ฐ ์๋ ํ ์ด๋ธ์ ๋ฐ์ดํฐ ์กฐํ ์ ํ ์ค์บ์ด ์ผ์ด๋์ง ์๊ธฐ ๋๋ฌธ์ ์ธ๋ฑ์ค๊ฐ ์๋ ํ ์ด๋ธ์ DRIVEN TABLE๋ก ๋๋ฉด ๋๋ผ์ด๋น ํ ์ด๋ธ์ด ๋๋ฆฌ๋ธ ํ ์ด๋ธ์ ๋ํด์ ๋ฐ๋ณต์ ์ผ๋ก ํ ์ค์บ์ ํ์ง ์์ ๋ ๋น ๋ฅด๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์ ์ธ๋ฑ์ค์ ์ ๋ฌด๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ฒฐ์ ๊ท์น์ ๋๋ ๋ณด๋ฉด
- ๋ ์นผ๋ผ ๋ชจ๋ ๊ฐ๊ฐ ์ธ๋ฑ์ค๊ฐ ์์ ๊ฒฝ์ฐ
- ๋ ์ฝ๋ ๊ฑด์์ ๋ฐ๋ผ ์ ์ ๋ ์ฝ๋ ์๋ฅผ ๊ฐ์ง ํ ์ด๋ธ์ ๋๋ผ์ด๋น ํ ์ด๋ธ๋ก
- ํ ์นผ๋ผ์๋ง ์ธ๋ฑ์ค๊ฐ ์๋ ๊ฒฝ์ฐ
- ์ธ๋ฑ์ค๊ฐ ์๋ ํ ์ด๋ธ์ ๋ฐ๋ณต๋ ํ ์ค์บ์ ๋ง๊ธฐ ์ํด ์ธ๋ฑ์ค๊ฐ ์๋ ํ ์ด๋ธ์ ๋๋ผ์ด๋น ํ ์ด๋ธ๋ก ์ ํ
- ๋ ์นผ๋ผ ๋ชจ๋ ์ธ๋ฑ์ค๊ฐ ์์ ๊ฒฝ์ฐ
- ์ค์บ๋๋ ๋ ์ฝ๋ ์์ ๋ฐ๋ผ ์ ์ ํ ๋๋ผ์ด๋น ํ ์ด๋ธ ์ ํ
- ๋๋ฆฌ๋ธ ํ ์ด๋ธ์ ํ์ค์บ
์ผ๋ก ๋์ํ๊ฒ ๋๋ค.
์ฐธ์กฐ
https://inpa.tistory.com/entry/MYSQL-%F0%9F%93%9A-JOIN-%EC%A1%B0%EC%9D%B8-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EA%B8%B0%EC%89%BD%EA%B2%8C-%EC%A0%95%EB%A6%AC https://devuna.tistory.com/36