...

SQL JOIN
JOIN์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ด์ ์ฌ๋ฌ ํ ์ด๋ธ์์ ๊ฐ์ ธ์จ ๋ ์ฝ๋๋ฅผ ์กฐํฉํ์ฌ ํ๋์ ํ ์ด๋ธ์ด๋ ๊ฒฐ๊ณผ ์งํฉ์ผ๋ก ํํํด ์ฃผ๋, Relation Database ์์ ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๋ ์์ด๋ค.

(INNER) JOIN
- ์กฐ์ธํ๋ ํ ์ด๋ธ์ ON ์ ์ ์กฐ๊ฑด์ด ์ผ์นํ๋ ๊ฒฐ๊ณผ๋ง ์ถ๋ ฅ
- ํ์ค SQL๊ณผ๋ ๋ฌ๋ฆฌ MySQL์์๋ JOIN, INNER JOIN, CROSS JOIN์ด ๋ชจ๋ ๊ฐ์ ์๋ฏธ๋ก ์ฌ์ฉ๋๋ค.

select u.userid, name
from usertbl as u inner join buytbl as b
on u.userid=b.userid
where u.userid="111" -- join์ ์๋ฃํ๊ณ ๊ทธ๋ค์ ์กฐ๊ฑด์ ๋ฐ์ง๋ค.
inner join ํจ์ถ ๊ตฌ๋ฌธ
๋จ์ํ from ์ ์ ์ฝค๋ง ์ฐ๋ฉด inner join ์ผ๋ก ์น๋ถ๋๋ค.
select u.userid, name
from usertbl u, buytbl b
where u.userid=b.userid and u.userid="111"
๋ค์์ ๋ฐฐ์ธ left outer join์ 1 : N ๊ด๊ณ์์ ์ด๋ ํ ์ด๋ธ์ ๊ธฐ์ค์ผ๋ก leftํ ๊ฒ์ด๋์ ๋ฐ๋ผ, ๋ ์ฝ๋ ๊ฐฏ์๊ฐ ๋ฌ๋ฆฌ์ง๊ฒ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ํ ์กฐ์ธ์ ๋ถํฉ๋์ง ์๋ ๋ ์ฝ๋๋ ํ ์ด๋ธ ๊ธฐ์ค์ ๋ฐ๋ผ ๋จ๊ธฐ๋ ํ๋ค.
ํ์ง๋ง inner join ์ ์ด๋ ํ ์ด๋ธ์์ ๊ธฐ์ค์ผ๋ก ์กฐ์ธํ๋ ์กฐ์ธ ๊ด๊ณ์ ๋ถํฉ๋๋ ๋ ์ฝ๋๋ฅผ ๋ชจ๋ ๊ฐ์ง๊ฒ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์กฐ์ธ์ ๋ถํฉ๋์ง ์๋ ๋ ์ฝ๋๋ ๋ชจ๋ ์ญ์ ๋๋ค.

LEFT / RIGHT OUTER JOIN
- ๋ ํ ์ด๋ธ์ด ํฉ์ณ ์ง๋ ์ผ์ชฝ/์ค๋ฅธ์ชฝ์ ๊ธฐ์ค์ผ๋ก ํ๋๋์ ๋ฐ๋ผ ๊ธฐ์ค ํ ์ด๋ธ์ ๊ฒ์ ๋ชจ๋ ์ถ๋ ฅ๋์ด์ผ ํ๋ค๊ณ ์ดํดํ๋ฉด ๋๋ค.
- OUTER JOIN์ ์กฐ์ธํ๋ ํ ์ด๋ธ์ ON ์ ์ ์กฐ๊ฑด ์ค ํ์ชฝ์ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ๊ฐ์ ธ์จ๋ค
- OUTER JOIN์ LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN ์ด๋ ๊ฒ 3๊ฐ์ง๊ฐ ์๋ค.
- LEFT OUTER JOIN์ ๊ฑฐ์ ๋๋ถ๋ถ ์ฌ์ฉํ์ฌ, FULL OUTER JOIN์ ์ฑ๋ฅ์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์๋๋ค.
โ
Left join

LEFT JOIN์ ๋ ํ ์ด๋ธ์ด ์์ ๊ฒฝ์ฐ, ์ฒซ ๋ฒ์งธ ํ ์ด๋ธ์ ๊ธฐ์ค์ผ๋ก ๋ ๋ฒ์งธ ํ ์ด๋ธ์ ์กฐํฉํ๋ JOIN์ด๋ค.
-- ์) 1ํ๋
ํ์์ ์ด๋ฆ๊ณผ ์ง๋๊ต์๋ช
์ ์ถ๋ ฅํ๋ผ. ๋จ, ์ง๋๊ต์๊ฐ ์ง์ ๋์ง ์์ ํ์๋ ์ถ๋ ฅ๋๊ฒ ํ๋ผ.
SELECT STUDENT.NAME, PROFESSOR.NAME
FROM STUDENT LEFT OUTER JOIN PROFESSOR -- STUDENT๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ ์กฐ์ธ
ON STUDENT.PID = PROFESSOR.ID
WHERE GRADE = 1
LEFT JOIN์ ์ฌ๋ฌ๋ฒ ํ ๋ ์ฃผ์ํ ์
1) INNER JOIN๊ณผ๋ ๋ฌ๋ฆฌ LEFT JOIN์ ์กฐ์ธํ๋ ํ ์ด๋ธ์ ์์๊ฐ ์๋นํ ์ค์ํ๋ค.
์ด๋ค ์์๋ก ํ ์ด๋ธ์ ์กฐ์ธํ๋์ง์ ๋ฐ๋ผ ๊ฒฐ๊ณผ ํ ์ด๋ธ์ ์กฐํ๋๋ ํ์ ๊ฐ์๋ฉฐ ๊ตฌ์ฑ ๋ฑ์ด ๋ฌ๋ผ์ง ์ ์๋ค.
๋ฐ๋ผ์ JOIN ๋ฌธ์ ์์ฑํ ๋, ๋ง์ฝ LEFT JOIN์ ํ ๊ฑฐ๋ผ๋ฉด ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ์ ํ ์ด๋ธ๋ก SELECT๋ฌธ์ ๊ฐ์ฅ ๋ง์ ์ด์ ๊ฐ์ ธ์์ผ ํ ํ ์ด๋ธ์ ์ฐ์ ์ผ๋ก ์ ์ด์ค๋ค.
2) ์กฐ์ธ์ ์ฌ๋ฌ ๋ฒ ํด์ผํ๋๋ฐ ์์์ LEFT JOIN์ผ๋ก ํ๋ค๋ฉด ๋๋จธ์ง ์กฐ์ธ๋ LEFT JOIN์ ์ด์ด๋๊ฐ๋ค.
์ฆ, LEFT JOIN์ ์ฐ๋ค๊ฐ ๊ฐ์๊ธฐ INNER JOIN ์ด๋ ๋ค๋ฅธ ์กฐ์ธ์ ์ฌ์ฉํ์ง ์๋๋ค๋ ์ด์ผ๊ธฐ๋ค.
Right join

RIGHT JOIN์ ๋ ํ ์ด๋ธ์ด ์์ ๊ฒฝ์ฐ, ๋ ๋ฒ์งธ ํ ์ด๋ธ์ ๊ธฐ์ค์ผ๋ก ์ฒซ ๋ฒ์งธ ํ ์ด๋ธ์ ์กฐํฉํ๋ JOIN์ด๋ค.
-- ์) 1ํ๋
ํ์์ ์ด๋ฆ๊ณผ ์ง๋๊ต์๋ช
์ ์ถ๋ ฅํ๋ผ. ๋จ, ์ง๋๊ต์๊ฐ ์ง์ ๋์ง ์์ ํ์๋ ์ถ๋ ฅ๋๊ฒ ํ๋ผ.
SELECT STUDENT.NAME, PROFESSOR.NAME
FROM STUDENT RIGHT OUTER JOIN PROFESSOR -- PROFESSOR๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ฅธ์ชฝ ์กฐ์ธ
ON STUDENT.PID = PROFESSOR.ID
WHERE GRADE = 1
3์ค ์กฐ์ธ
๋ง์ผ ์ํ๋ ์ ๋ณด๊ฐ ํ ์ด๋ธ 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

select *
from topic FULL OUTER JOIN autor
on topic.auther_id = authoer.id
๋๋ถ๋ถ DB๋ FULL OUTER JOIN์ ์ง์ํ์ง ์๋๋ค. ํ์ง๋ง ๊ฐ์ ์ ์ผ๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ด ์กด์ฌํ๋ค
โ
= (๊ฐ์ ๊ตฌ๋ฌธ)
(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))
* LEFT ์กฐ์ธํ ํ ์ด๋ธ๊ณผ RIGHT์กฐ์ธํ ํ ์ด๋ธ์ UNION ํฉ์งํฉ ํด์ฃผ๋ฉด ๋๋ค.
* UNION ์ DISTICT์๋ ํฌํจ์ด๋ผ, ๋ฐ๋ก ์ค๋ณต์ ๊ฑฐ ์ํด์ค๋ ์๋์ผ๋ก ์ค๋ณต์ ๊ฑฐ ํด์ค๋ค
UNION
- UNION์ ์ฌ๋ฌ ๊ฐ์ SELECT ๋ฌธ์ ๊ฒฐ๊ณผ๋ฅผ ํ๋์ ํ ์ด๋ธ์ด๋ ๊ฒฐ๊ณผ ์งํฉ์ผ๋ก ํํํ ๋ ์ฌ์ฉ
- ์ด๋ ๊ฐ๊ฐ์ SELECT ๋ฌธ์ผ๋ก ์ ํ๋ ํ๋์ ๊ฐ์์ ํ์ ์ ๋ชจ๋ ๊ฐ์์ผ ํ๋ฉฐ, ํ๋์ ์์ ๋ํ ๊ฐ์์ผ ํ๋ค.
- ๊ธฐ๋ณธ ์งํฉ ์ฟผ๋ฆฌ์๋ (DISTINCT) ์ค๋ณต์ ๊ฑฐ๊ฐ ์๋ ํฌํจ๋์ด์๋ค.
SELECT ํ๋์ด๋ฆ FROM ํ
์ด๋ธ์ด๋ฆ
UNION
SELECT ํ๋์ด๋ฆ FROM ํ
์ด๋ธ์ด๋ฆ
UNION ALL
- UNION์ DISTINCT ์๋ ํฌํจ์ด๋ผ ์ค๋ณต๋๋ ๋ ์ฝ๋๋ฅผ ์ ๊ฑฐํ๋ค.
- ๋ฐ๋ผ์ ์ค๋ณต๋๋ ๋ ์ฝ๋๊น์ง ๋ชจ๋ ์ถ๋ ฅํ๊ณ ์ถ๋ค๋ฉด, ALL ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
SELECT ํ๋์ด๋ฆ FROM ํ
์ด๋ธ์ด๋ฆ
UNION ALL
SELECT ํ๋์ด๋ฆ FROM ํ
์ด๋ธ์ด๋ฆ
EXCLUSIVE LEFT JOIN
- ์ด๋ ํน์ ํ ์ด๋ธ์ ์๋ ๋ ์ฝ๋๋ง ๊ฐ์ ธ์ค๋ ๊ฒ

โEXCLUSIVE JOIN๋ ๋ง์ฝ ํ ์ด๋ธ ๋๊ฐ๋ฅผ JOINํ๋ค๋ฉด ๋์ค ํ๊ฐ์ง ํ ์ด๋ธ์๋ง ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค.
๋ค๋ฅธ JOIN๋ค๊ณผ๋ ๋ค๋ฅด๊ฒ ๋ณ๋์ EXCLUSIVE JOINํจ์๊ฐ ์๋ ๊ฒ์ ์๋๊ณ ๊ธฐ์กด์ LEFT JOIN๊ณผ Where์ ์ ์กฐ๊ฑด์ ํจ๊ป ์ฌ์ฉํ์ฌ ๋ง๋๋ JOIN ๋ฌธ๋ฒ์ด๋ค.
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)
- ๋ง ๊ทธ๋๋ก ํ ์ด๋ธ ์๊ธฐ์์ ์ ์กฐ์ธ ํ ๊ฒ
-- ์) ๋ชจ๋ ์ฌ์์ ๋ํด ์ฌ์์ ์ด๋ฆ๊ณผ ์ง์ ์์ฌ์ ์ด๋ฆ์ ๊ฒ์ ํด๋ผ.
-- EMPNAME ํ
์ด๋ธ์ ์ด๋ค ์ฌ์์ MANAGER ๋ฒํธ๊ฐ ๊ฐ์ ํ
์ด๋ธ ๋ด์์ ์ด๋ค ์ฌ์์ EMPNO์ ๊ฐ์ผ๋ฉด ๊ทธ ์ฌ์์ด ์ง์ ์๊ด
SELECT E.EMPNAME as ์ฌ์, M.EMPNAME as ์ง์์๊ด
FROM EMPLOYEE E, EMPLOYEE M -- inner join
WHERE E.MANAGER = M.EMPNO;

JOIN์์ ์ค๋ณต๋ ๋ ์ฝ๋ ์ ๊ฑฐํ๊ธฐ
โ
Distinct ์ฌ์ฉ
- mysql์์ ์ง์ํ๋ distinct ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
- ๋งค์ฐ ์ฌ์ด ๋ฐฉ๋ฒ์ด์ง๋ง ๋ ์ฝ๋ ์๊ฐ ๋ง์ ๊ฒฝ์ฐ ์ฑ๋ฅ์ด ๋๋ฆฌ๋ค๋ ๋จ์ ์ด ์๋ค.
-- DISTINCT๋ฅผ ์ถ๊ฐ
SELECT DISTINCT person.id, person.name, job.job_name
FROM person INNER JOIN job
ON person.name = job.person_name;
JOIN ์ ์ ์ค๋ณต์ ์ ๊ฑฐํ๊ธฐ
- ์์ ๋งํ ๊ฒ์ฒ๋ผ SELECT DISTINCT๋ ๊ฐ๋จํ์ง๋ง ์ฑ๋ฅ์ด ๋๋ฆฌ๋ค.
- ์ฑ๋ฅ์ ์ํด์๋ JOIN ์ ์ ์ค๋ณต์ ์ ๊ฑฐํ๋ ์์ ์ ํด์ฃผ๋ ๊ฒ์ด ์ข๋ค. (๋ฌผ๋ก ๋ ์ข์ ๊ฒ์ ์ค๋ณต์ด ์๋๋ก ํ ์ด๋ธ ์ค๊ณ๋ฅผ ์ ํ๋ ๊ฒ์ด๋ค)
JOIN ์ ์ ์ค๋ณต ์ ๊ฑฐ๋ ๋ค์๊ณผ ๊ฐ์ด ์กฐ์ธํ ํ ์ด๋ธ์ ์๋ธ์ฟผ๋ฆฌ์ inline view๋ฅผ ์ฌ์ฉํด distinct ํ๊ณ ์กฐ์ธํ๋ฉด ๋๋ค.
select A.name, A.countryCode
from city A
left join ( select distinct name, Code from country ) as B
-- ์กฐ์ธํ ํ
์ด๋ธ์ ๋จผ์ distinct๋ก ์ค๋ณต์ ์ ๊ฑฐํ select๋ฌธ์ ์๋ธ์ฟผ๋ฆฌ๋ก ๋ถ๋ฌ์ ์์ํ
์ด๋ธ๋ก ๋ง๋ ๋ค ์กฐ์ธํ๋ค
on A.countrycode = B.Code
์ธ๋ป๋ณด๋ฉด ๋ณต์กํด๋ณด์ผ ์ ์๊ณ ์ฑ๋ฅ์ด ๋ ๋๋ ค๋ณด์ผ ์ ์๋๋ฐ, ์ผ๋ฐ์ ์ผ๋ก ๋ ์ฝ๋ ์๊ฐ ๋ง์ ๊ฒฝ์ฐ JOIN ์ ์ ์ค๋ณต์ ์ ๊ฑฐํด์ 1:1 JOIN์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ์ด ํจ์ฌ ๋น ๋ฅด๋ค.
๋ฌผ๋ก WHERE ์ ์ ์กฐ๊ฑด์ด ์กด์ฌ ์ฌ๋ถ, index ์กด์ฌ ์ฌ๋ถ, ํ์ชฝ ํ ์ด๋ธ์ ํฌ๊ธฐ๊ฐ ์์ฒญ ์ ์ ๊ฒฝ์ฐ ๋ฑ๋ฑ ๋ง์ ์๋๋ฆฌ์ค๊ฐ ์์ผ๋ ์ฑ๋ฅ ๋น๊ต๋ฅผ ํ๋ ๊ฒ์ด ์ข๋ค.
์ด ๊ธ์ด ์ข์ผ์ จ๋ค๋ฉด ๊ตฌ๋ & ์ข์์
์ฌ๋ฌ๋ถ์ ๊ตฌ๋
๊ณผ ์ข์์๋
์ ์์๊ฒ ํฐ ํ์ด ๋ฉ๋๋ค.