8.1. JOIN์ด๋?8.1.1. PK ์ FK8.1.2. JOIN์ ์ ํ8.1.3. JOIN ๋ฌธ๋ฒ8.2. JOIN ์ฐ์ฐ8.2.1. INNER JOIN8.2.2. LEFT JOIN8.2.3. RIGHT JOIN8.2.4. FULL OUTER JOIN8.2.5. CROSS JOIN8.2.6. SELF JOIN
ย
8.1. JOIN์ด๋?
์กฐ์ธ์ ์ค๋ช
ํ๊ธฐ ์์ RDBMS(Relational Database Management System) ํ
์ด๋ธ์ ํน์ง์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. RDMS์์ ๋ฐ์ดํฐ๋ ํ
์ด๋ธ ํํ๋ก ์ ์ฅ๋ฉ๋๋ค. ํ
์ด๋ธ๋ค์ ๋ชฉ์ ๊ณผ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ด, ๋ฐ์ดํฐ์ ์ค๋ณต์ฑ์ ์ค์ด๊ณ ํจ์จ์ ์ธ ๊ด๋ฆฌ๋ฅผ ์ํด ๋ถ๋ฆฌํ์ฌ ์ ์ฅํฉ๋๋ค.
๋ฐ์ดํฐ ์ ๊ทํ
- ๋ฐ์ดํฐ ์ ๊ทํ๋ ๋ฐ์ดํฐ์ ์ค๋ณต์ ์ ๊ฑฐํ๊ณ ๋ฌด๊ฒฐ์ฑ์ ํ๋ณดํ๊ธฐ ์ํ ๊ณผ์ ์ ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ ์, ๋ฐ์ดํฐ์ ์ค๋ณต์ ์ต์ํํ๊ณ , ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ๊ณผ ์ผ๊ด์ฑ์ ์ ์งํ๊ธฐ ์ํด ์ฌ๋ฌ ํ ์ด๋ธ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฆฌํฉ๋๋ค.
- ์๋ฅผ ๋ค๋ฉด, ๊ณ ๊ฐ ์ ๋ณด์ ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ ๋ณ๋์ ํ ์ด๋ธ๋ก ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ์ ํจ์จ์ ๊ด๋ฆฌ
- ๊ฐ ํ ์ด๋ธ์ ๊ทธ ํ ์ด๋ธ๋ง์ ํน์ ํ ์ฃผ์ ๋ ๋ชฉ์ ์ ๋ง๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค.
- ๋ฐ์ดํฐ์ ์ฝ์ , ์์ , ์ญ์ ๋ฑ์ ์์ ์ด ํ ์ด๋ธ ๋ณ๋ก ๋ ๋ฆฝ์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋ฏ๋ก ๋ฐ์ดํฐ ๊ด๋ฆฌ์ ํจ์จ์ด ์ฆ๊ฐํฉ๋๋ค.
๋ฐ์ดํฐ ๋ณด์ ๊ฐํ
- ํ ์ด๋ธ ๋ณ๋ก ์ ๊ทผ ๊ถํ์ ์ค์ ํ ์ ์์ด, ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ ์ ์์ต๋๋ค.
- ๊ธ์ฌ๋ ๊ฐ์ธ ์ ๋ณด ๊ฐ์ ๋ฏผ๊ฐ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ ํ ์ด๋ธ์ ์ ๊ทผ์ ์ ํํ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ํ
์ด๋ธ์ ๋ถ๋ฆฌํ์ฌ ์ ์ฅํ๋ ๊ฒ์ ์ค๋ณต์ฑ์ ์ค์ด๊ณ ํจ์จ์ฑ์ ๋์ด๋ ๋ฐ ํฐ ๋์์ด ๋์ง๋ง, ๋๋ก๋ ์ด๋ฌํ ๋ถ๋ฆฌ๋ ํ
์ด๋ธ๋ค์ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ์กฐํํด์ผ ํ ๋๊ฐ ์์ต๋๋ค. ์ด๋ JOIN ์ฐ์ฐ์ด ์ค์ํ๊ฒ ์์ฉํฉ๋๋ค.
JOIN
์ SQL์ ํต์ฌ ๊ธฐ๋ฅ ์ค ํ๋๋ก, ๋ ๊ฐ ์ด์์ ํ
์ด๋ธ์์ ๊ด๋ จ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฒฐํฉํ์ฌ ํ๋์ ๊ฒฐ๊ณผ๋ก ๋ฐํํ๋ ์ฐ์ฐ์
๋๋ค. ์ด๋ฅผ ํตํด ๋ถ๋ฆฌ๋ ํ
์ด๋ธ ๊ฐ์ ๊ด๊ณ๋ฅผ ํ์ฉํ์ฌ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด, ๊ณ ๊ฐ ์ ๋ณด๊ฐ ์ ์ฅ๋ ํ
์ด๋ธ๊ณผ ์ฃผ๋ฌธ ์ ๋ณด๊ฐ ์ ์ฅ๋ ํ
์ด๋ธ์ JOIN ํ์ฌ, ํน์ ๊ณ ๊ฐ์ ์ฃผ๋ฌธ ๋ด์ญ์ ํ ๋ฒ์ ์ฟผ๋ฆฌ๋ก ์กฐํํ ์ ์์ต๋๋ค.ย
8.1.1. PK ์ FK
SQL์์ JOIN ์ฐ์ฐ์ ์ํํ ๋, ํ
์ด๋ธ๋ค ์ฌ์ด์ ์ฐ๊ฒฐ๊ณ ๋ฆฌ ์ญํ ์ ํ๋ ์ฃผ์ ์์๋ "Key(ํค)"์
๋๋ค. ์ด๋ฌํ ํค๋ Primary Key(๊ธฐ๋ณธ ํค)์ Foreign Key(์ธ๋ ํค) ๋ ๊ฐ์ง ์ ํ์ผ๋ก ๋๋ฉ๋๋ค. ํด๋น ํค๋ค์ ํตํด ํ
์ด๋ธ ๊ฐ์ ๊ด๊ณ๋ฅผ ์ ์ํ๊ณ , JOIN ์ฐ์ฐ์ ํตํด ๋ฐ์ดํฐ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์กฐํํ๋ ํ ์ ์์ต๋๋ค.
Primary Key(PK)
- Primary Key๋ ํ ์ด๋ธ ๋ด์์ ๊ฐ ๋ ์ฝ๋๋ฅผ ๊ณ ์ ํ๊ฒ ๊ตฌ๋ถํ๋ ์ญํ ์ ํฉ๋๋ค.
- ์ค๋ณต๋ ๊ฐ์ ํ์ฉํ์ง ์์ผ๋ฉฐ,
NULL
๊ฐ์ ๊ฐ์ง ์ ์์ต๋๋ค.
- ํ๋์ ํ ์ด๋ธ ๋ด์๋ ์ค์ง ํ๋์ Primary Key๋ง ์กด์ฌํ ์ ์์ต๋๋ค.
Foreign Key(FK)
- Foreign Key๋ ๋ค๋ฅธ ํ ์ด๋ธ์ Primary Key๋ฅผ ์ฐธ์กฐํ๋ ํค๋ก, ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ ํ ์ด๋ธ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ํ๋ด๋ ์ค์ํ ์์์ ๋๋ค.
- Foreign Key๋ฅผ ํตํด ์ฐธ์กฐ ๋ฌด๊ฒฐ์ฑ(Referential Integrity)์ ๋ณด์ฅํฉ๋๋ค. ์ด๋ Foreign Key๊ฐ ์ฐธ์กฐํ๋ ๋ค๋ฅธ ํ ์ด๋ธ์ Primary Key ๊ฐ๊ณผ ์ผ์นํด์ผ ํจ์ ์๋ฏธํฉ๋๋ค.
- ํ๋์ ํ ์ด๋ธ์ ์ฌ๋ฌ Foreign Key๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ๊ฐ๊ฐ ๋ค๋ฅธ ํ ์ด๋ธ์ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
JOIN ์ฐ์ฐ์ ์งํํ ๋, FK์ PK ๊ฐ์ ๊ด๊ณ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฒฐํฉํฉ๋๋ค. ์์๋ก, HR ๋ฐ์ดํฐ ์
์ ์ดํด๋ณด๋ฉด โemployeesโ ํ
์ด๋ธ์๋ ์ฌ์์ ๋ํ ์ ๋ณด๊ฐ, โdepartmentsโ ํ
์ด๋ธ์๋ ๋ถ์์ ๋ํ ์ ๋ณด๊ฐ ์ ์ฅ๋์ด ์์ต๋๋ค. โemployeesโ ํ
์ด๋ธ์ FK๋ฅผ ์ฌ์ฉํ์ฌ โdepartmentsโ ํ
์ด๋ธ์ PK๋ฅผ ์ฐธ์กฐํ๋ฉด, ๊ฐ ์ฌ์์ด ์ด๋ค ๋ถ์์ ์ํด ์๋์ง ์ ์ ์๊ฒ ๋ฉ๋๋ค. ์ด๋ ๊ฒ JOIN ์ฐ์ฐ์ ํตํด ๋ ํ
์ด๋ธ์ ๊ด๋ จ ์ ๋ณด๋ฅผ ํจ๊ป ์กฐํํ๊ฒ ๋๋ ๊ฒ์
๋๋ค.
.png?table=block&id=fe554bee-7837-40ad-b04b-362bc63992c7&cache=v2)
ย
8.1.2. JOIN์ ์ ํ
BigQuery๋ ๋ค์ํ JOIN ์ ํ์ ์ง์ํฉ๋๋ค.
1. INNER JOIN
- ์ด๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ JOIN ์ ํ์ผ๋ก, ๋ ํ ์ด๋ธ ๊ฐ์ ์ผ์นํ๋ ๋ ์ฝ๋๋ง ๋ฐํํฉ๋๋ค.
- ์กฐ๊ฑด์ ์ผ์นํ์ง ์๋ ๋ ์ฝ๋๋ ๊ฒฐ๊ณผ์์ ์ ์ธ๋ฉ๋๋ค.
2. LEFT OUTER JOIN (๋๋ LEFT JOIN)
- ์ผ์ชฝ ํ ์ด๋ธ์ ๋ชจ๋ ๋ ์ฝ๋์ ์ค๋ฅธ์ชฝ ํ ์ด๋ธ์์ ์กฐ๊ฑด์ ์ผ์นํ๋ ๋ ์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค.
- ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์ ์ผ์นํ๋ ๋ ์ฝ๋๊ฐ ์๋ ๊ฒฝ์ฐ, ํด๋น ํ๋๋
NULL
๋ก ํ์๋ฉ๋๋ค.
3. RIGHT OUTER JOIN (๋๋ RIGHT JOIN)
- ์ค๋ฅธ์ชฝ ํ ์ด๋ธ์ ๋ชจ๋ ๋ ์ฝ๋์ ์ผ์ชฝ ํ ์ด๋ธ์์ ์กฐ๊ฑด์ ์ผ์นํ๋ ๋ ์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค.
- ์ผ์ชฝ ํ
์ด๋ธ์ ์ผ์นํ๋ ๋ ์ฝ๋๊ฐ ์๋ ๊ฒฝ์ฐ, ํด๋น ํ๋๋
NULL
๋ก ํ์๋ฉ๋๋ค.
4. FULL OUTER JOIN (๋๋ FULL JOIN)
- ๋ ํ ์ด๋ธ์ ๋ชจ๋ ๋ ์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค.
- ๋ ํ
์ด๋ธ ์ค ์ด๋ ํ์ชฝ์๋ง ์กด์ฌํ๋ ๋ ์ฝ๋๋ ๋ค๋ฅธ ํ
์ด๋ธ์ ํ๋ ๊ฐ์ด
NULL
๋ก ํ์๋ฉ๋๋ค.
5. CROSS JOIN
- ๋ ํ ์ด๋ธ์ ๋ชจ๋ ๊ฐ๋ฅํ ์กฐํฉ์ ๋ฐํํฉ๋๋ค.
- ์ด JOIN ์ ํ์ ํน๋ณํ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉ๋๋ฉฐ, ๋ ํ ์ด๋ธ ๊ฐ์ ์ผ์น ์กฐ๊ฑด ์์ด ๋ชจ๋ ์กฐํฉ์ ๊ฒฐ๊ณผ๋ฅผ ์ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
6. SELF JOIN
- ํ ์ด๋ธ์ ์๊ธฐ ์์ ๊ณผ JOIN ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- ๊ฐ์ ํ ์ด๋ธ ๋ด์์ ๋ ์ฝ๋ ๊ฐ์ ๊ด๊ณ๋ฅผ ์ฐพ์ ๋ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ง์๊ณผ ์์ฌ์ด ๋ชจ๋ ๊ฐ์ ํ ์ด๋ธ์ ์์ ๊ฒฝ์ฐ, SELF JOIN์ ์ฌ์ฉํ์ฌ ์์ฌ-์ง์ ๊ด๊ณ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
ย
8.1.3. JOIN ๋ฌธ๋ฒ
JOIN ์ฐ์ฐ์ ANSI JOIN๊ณผ Oracle JOIN, ๋ ์ข
๋ฅ์ SQL ๋ฌธ๋ฒ์ด ์์ต๋๋ค. ์๋์์ ๊ฐ JOIN ๋ฌธ๋ฒ์ ์ค๋ช
๋ฐ ์ฃผ์ ์ฐจ์ด์ ์ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ANSI JOIN
American National Standards Institute (ANSI)์ ์ํด ์ ์๋ ํ์ค SQL JOIN์
๋๋ค.
- ํน์ง: JOIN ํค์๋์ ํจ๊ป ์กฐ์ธ ์กฐ๊ฑด์ ๋ช ์์ ์ผ๋ก ON ์ ์์ ์ ๊ณตํฉ๋๋ค.
- ๊ตฌ๋ฌธ:
# INNER JOIN SELECT * FROM Table1 INNER JOIN Table2 ON Table1.column = Table2.column;
ย
ORACLE JOIN
ORACLE JOIN์ Oracle ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ ํต์ ์ผ๋ก ์ฌ์ฉ๋๋ JOIN ๋ฐฉ์์
๋๋ค.
- ํน์ง: WHERE ์ ์ ์ฌ์ฉํ์ฌ ๋ ํ ์ด๋ธ ๊ฐ์ ์กฐ์ธ ์กฐ๊ฑด์ ์ ๊ณตํฉ๋๋ค.
- ๊ตฌ๋ฌธ:
# INNER JOIN SELECT * FROM Table1 , Table2 WHERE Table1.column = Table2.column;
ย
์ฃผ์ ์ฐจ์ด์
- ๊ตฌ๋ฌธ: ANSI JOIN์
JOIN
ํค์๋์ON
์ ์ ์ฌ์ฉํ๋ฉฐ, ORACLE JOIN์,
(์ฝค๋ง)์WHERE
์ ์ ์ฌ์ฉํฉ๋๋ค.
- ํ์ค์ฑ: ANSI JOIN์ ANSI SQL ํ์ค์ ๋ฐ๋ฅธ ๊ฒ์ด๋ฏ๋ก ๋ค์ํ RDBMS์์ ํธํ์ฑ์ ๊ฐ์ง๋๋ค. ๋ฐ๋ฉด, ORACLE JOIN์ Oracle ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํนํ๋ ๋ฐฉ์์ ๋๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก, ANSI JOIN์ ํ์ค SQL์ ๋ฐ๋ฅธ ์กฐ์ธ ๋ฐฉ์์ ๋ํ๋ด๋ฉฐ, ORACLE JOIN์ Oracle ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ํต์ ์ธ ์กฐ์ธ ๋ฐฉ์์ ๋ํ๋
๋๋ค. ํ์ง๋ง ์ต์ ๋ฒ์ ์ Oracle ๋ฐ์ดํฐ๋ฒ ์ด์ค์์๋ ANSI JOIN ๊ตฌ๋ฌธ์ ์ง์ํ๋ฏ๋ก, ํ์คํ์ ํธํ์ฑ์ ์ํด ANSI ๋ฐฉ์์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
ย
8.2. JOIN ์ฐ์ฐ
8.2.1. INNER JOIN
INNER JOIN์ ๋ ํ
์ด๋ธ ๊ฐ์ ์ง์ ๋ ์กฐ๊ฑด์ ๋ง๋ ๋ฐ์ดํฐ๋ง ๋ฐํํ๋ JOIN ๋ฐฉ์์
๋๋ค. ์ฆ, ๋ ํ
์ด๋ธ์์ ์ง์ ๋ ์กฐ๊ฑด์ ๋ฐ๋ผ ์ผ์นํ๋ ๊ฐ์ด ์๋ ํ๋ง ๊ฒฐํฉํ์ฌ ๋ฐํํฉ๋๋ค. ์ผ์นํ๋ ๊ฐ์ด ์๋ ํ์ ๊ฒฐ๊ณผ์์ ์ ์ธ๋ฉ๋๋ค. ๋ถํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ์ธํ๊ณ , ๊ด๋ จ๋ ๋ฐ์ดํฐ๋ง ์กฐํํ ๋ ํจ์จ์ ์ด๋ฉฐ, ๊ฒฐ๊ณผ ์งํฉ์ ํฌ๊ธฐ๋ฅผ ์ต์ํํ์ฌ ์ฒ๋ฆฌ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
# ANSI SQL JOIN SELECT * FROM Table1 [INNER] JOIN Table2 ON Table1.column = Table2.column; # ORACLE SQL JOIN SELECT * FROM Table1 , Table2 WHERE Table1.column = Table2.column;
ANSI ๋ฌธ๋ฒ์ JOIN์ ํ์ค SQL JOIN ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ฉฐ, Oracle์์ ์ ํต์ ์ผ๋ก ์ฌ์ฉ๋๋ JOIN ๊ตฌ๋ฌธ์ WHERE ์ ์ ์ฌ์ฉํ์ฌ ๋ ํ
์ด๋ธ์ ๊ฒฐํฉํฉ๋๋ค.
ย
ANSI INNER JOIN:
JOIN ์กฐ๊ฑด์ด ๋ช
์์ ์ผ๋ก
INNER JOIN โฆ ON
๋ถ๋ถ์ ํ์๋๋ฏ๋ก ์ฟผ๋ฆฌ์ ๊ฐ๋
์ฑ์ด ์ข์ต๋๋ค. ์ด๋ก ์ธํด JOIN ์กฐ๊ฑด๊ณผ WHERE ์ ์ ํํฐ ์กฐ๊ฑด์ ๋ช
ํํ๊ฒ ๊ตฌ๋ถํ ์ ์์ต๋๋ค.ย
ORACLE INNER JOIN:
์ ํต์ ์ธ Oracle JOIN ๋ฐฉ์์
WHERE
์ ์์ JOIN ์กฐ๊ฑด์ ํฌํจํ๋ฏ๋ก, JOIN ์กฐ๊ฑด๊ณผ ๋ค๋ฅธ ํํฐ๋ง ์กฐ๊ฑด์ ๊ตฌ๋ถํ๊ธฐ๊ฐ ๋ ์ด๋ ค์ธ ์ ์์ต๋๋ค.ย
์ดํด๋ฅผ ๋๊ธฐ ์ํด HR ๋ฐ์ดํฐ ์
๋ด์ ์๋ โemployeesโ ํ
์ด๋ธ๊ณผ โdepartmentsโ ํ
์ด๋ธ์ INNER JOIN์ ํ์ฉํ์ฌ ๊ฒฐํฉํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ๋ ํ
์ด๋ธ ๋ชจ๋ โdepartment_idโ๋ผ๋ ๊ณตํต๋ ์ปฌ๋ผ์ด ์์ต๋๋ค. employees ํ
์ด๋ธ์์๋ โdepartment_idโ ์ปฌ๋ผ์ด FK์ด๋ฉฐ, department ํ
์ด๋ธ์์๋ โdepartment_idโ ์ปฌ๋ผ์ด ๋น์ฐํ PK ์ญํ ์ ์ํํฉ๋๋ค.

ย
๊ฐ ํ
์ด๋ธ์ โdepartment_idโ ๊ฐ์ด ๊ฐ์ ํ๋ผ๋ฆฌ ํฉ์ณ์ ธ์ ํ๋์ ํ
์ด๋ธ์ ๋ฐํํฉ๋๋ค. ํ์ง๋ง ์ฃผ์ํด์ผ ํ ์ ์ผ๋ก๋ ๋ ํ
์ด๋ธ ๋ชจ๋ โdepartment_idโ ์ปฌ๋ผ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์
SELECT
์์ ์ด๋ ํ
์ด๋ธ์ ์ปฌ๋ผ์ ๊ฐ์ ธ์ฌ ๊ฒ์ธ์ง ๋ฐ๋์ ๋ช
์ํด์ผ ํฉ๋๋ค.๋ํ, ๊ฐ ํ
์ด๋ธ์ ๋ณ์นญ์ ํ์ฉํ๋ฉด ๋ณต์กํ ํ
์ด๋ธ ์ด๋ฆ์ ๊ฐ๋จํ ๋ช ๊ธ์๋ก ์ค์ผ ์ ์์ด(
ON
์ ์์ ๋ณ์นญ ์ฌ์ฉ ๊ฐ๋ฅ), ์ ์ฒด์ ์ธ ์ฟผ๋ฆฌ์ ๊ธธ์ด์ ๋ณต์ก์ฑ์ ์ค์ผ ์ ์์ต๋๋ค. 
์๋์ ์์๋ โemployeesโ ํ
์ด๋ธ๊ณผ โdepartmentsโ ํ
์ด๋ธ์ ๊ฒฐํฉํ์ฌ ์ฌ์ ๋ฒํธ, ์ฌ์ ์ด๋ฆ, ๋ถ์ ๋ฒํธ ๊ทธ๋ฆฌ๊ณ ๋ถ์ ์ด๋ฆ์ ์กฐํํ ๊ฒฐ๊ณผ์
๋๋ค.
# ANSI SQL JOIN SELECT e.employee_id , CONCAT(e.first_name, e.last_name) AS name , d.department_id , d.department_name FROM `HR.employees` AS e JOIN `HR.departments` AS d ON e.department_id = d.department_id; # ORACLE SQL JOIN SELECT e.employee_id , CONCAT(e.first_name, e.last_name) AS name , d.department_id , d.department_name FROM `HR.employees` AS e , `HR.departments` AS d WHERE e.department_id = d.department_id;

ย
์ถ๊ฐ์ ์ธ ์์๋ก INNER JOIN ์ ์ฃผ์ํ ์ ์ ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. โemployeesโ ํ
์ด๋ธ๊ณผ โdepartmentsโ ํ
์ด๋ธ์ INNER JOINํ๊ณ ์ฌ์ ๋ฒํธ๊ฐ 170 ๋ณด๋ค ํฐ ๊ฒฝ์ฐ๋ฅผ ์กฐํํ์ต๋๋ค. ํด๋น ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์ฌ์ ๋ฒํธ 178๋ฒ์ ๋ ์ฝ๋๊ฐ ์กฐํ๋์ง ์์์ ํ์ธํ ์ ์์ต๋๋ค.
# ANSI SQL JOIN SELECT e.employee_id , CONCAT(e.first_name, e.last_name) AS name , d.department_id , d.department_name FROM `HR.employees` AS e JOIN `HR.departments` AS d ON e.department_id = d.department_id WHERE e.employee_id > 170; # ORACLE SQL JOIN SELECT e.employee_id , CONCAT(e.first_name, e.last_name) AS name , d.department_id , d.department_name FROM `HR.employees` AS e , `HR.departments` AS d WHERE e.department_id = d.department_id AND e.employee_id > 170;

ย
HR ๋ฐ์ดํฐ ์
์ โemployeesโ ํ
์ด๋ธ์ ์ฌ์๋ฒํธ๊ฐ 178์ธ ๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด โdepartment_idโ ๊ฐ
NULL
์
๋๋ค. JOIN ์กฐ๊ฑด์ธ JOIN ... ON
e.department_id = d.department_id
์ ๋ง์กฑํ์ง ์๊ธฐ ๋๋ฌธ์, ์ INNER JOIN์ ๊ฒฐ๊ณผ์์ ์ฌ์ ๋ฒํธ๊ฐ 178๋ฒ์ธ ํ์ ํฌํจ๋์ง ์์์ต๋๋ค.SELECT employee_id , CONCAT(first_name, last_name) AS name , department_id FROM `HR.employees` WHERE employee_id = 178;

ย
์ด์ ์ฌ์์ ๋ถ์์ ํด๋น ๋ถ์์ ์ฃผ์ ์ ๋ณด๋ฅผ INNER JOIN์ ํตํด ์์๋ณด๋ ค ํฉ๋๋ค. ์ฐ์ , โemployeesโ ํ
์ด๋ธ์์ "departments_id"๋ฅผ ์ฌ์ฉํด โdepartmentsโ ํ
์ด๋ธ์ ์ฐธ์กฐํ์ฌ ๋ถ์๋ช
์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์์ธ ์ฃผ์์ ๋์ ์ ๋ณด๋ โdepartmentsโ ํ
์ด๋ธ์ "location_id"๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐํฉํ โlocationsโ ํ
์ด๋ธ์์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ๋ง์ง๋ง์ผ๋ก, โlocationsโ ํ
์ด๋ธ ๋ด์ "country_id"๋ฅผ ํตํด โcountriesโ ํ
์ด๋ธ๊ณผ ๊ฒฐํฉํ์ฌ ๊ตญ๊ฐ ์ ๋ณด๊น์ง ํ์
ํ ์ ์์ต๋๋ค.
# ANSI SQL JOIN SELECT e.employee_id , CONCAT(e.first_name, e.last_name) AS name , d.department_name , l.street_address , l.city , l.state_province , c.country_name FROM `HR.employees` AS e JOIN `HR.departments` AS d ON e.department_id = d.department_id JOIN `HR.locations` AS l ON d.location_id = l.location_id JOIN `HR.countries` AS c ON l.country_id = c.country_id; # ORACLE SQL JOIN SELECT e.employee_id , CONCAT(e.first_name, e.last_name) AS name , d.department_name , l.street_address , l.city , l.state_province , c.country_name FROM `HR.employees` AS e , `HR.departments` AS d , `HR.locations` AS l , `HR.countries` AS c WHERE e.department_id = d.department_id AND d.location_id = l.location_id AND l.country_id = c.country_id ORDER BY 1;

ย
8.2.2. LEFT JOIN
LEFT JOIN, ๋๋ LEFT OUTER JOIN์ ์ผ์ชฝ ํ
์ด๋ธ์ ๋ชจ๋ ๋ ์ฝ๋์ ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์์ ์ผ์นํ๋ ๋ ์ฝ๋๊ฐ ๋ฐํ๋ฉ๋๋ค. ์ผ์นํ๋ ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์ ๋ ์ฝ๋๊ฐ ์๋ ๊ฒฝ์ฐ, ๊ฒฐ๊ณผ์๋
NULL
๊ฐ์ด ํฌํจ๋ฉ๋๋ค.LEFT JOIN์ ์ฃผ๋ก ์ผ์ชฝ ํ
์ด๋ธ์ ๋ชจ๋ ๋ ์ฝ๋๋ฅผ ํฌํจํ ๊ฒฐ๊ณผ๋ฅผ ์ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ชจ๋ ์ ํ๊ณผ ํด๋น ์ ํ์ ๋ํ ์ฃผ๋ฌธ(์๋ ๊ฒฝ์ฐ)์ ๋ณด์ฌ์ฃผ๊ณ ์ถ์ ๋ LEFT JOIN์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ย

LEFT JOIN ๋ฌธ๋ฒ์
LEFT JOIN
๋๋ LEFT OUTER JOIN
ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ํ
์ด๋ธ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ช
์์ ์ผ๋ก ํํํฉ๋๋ค.# ANSI SQL JOIN SELECT * FROM Table1 LEFT [OUTER] JOIN Table2 ON Table1.column = Table2.column;
ย
HR ๋ฐ์ดํฐ ์
์ ํ
์ด๋ธ๋ค์ LEFT JOIN์ ํ์ฉํ์ฌ ๊ฒฐํฉํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์๋์ ์์๋ โemployeesโ ํ
์ด๋ธ๊ณผ โdepartmentsโ ํ
์ด๋ธ์ ๊ฒฐํฉํ์ฌ ์ฌ์ ๋ฒํธ, ์ฌ์ ์ด๋ฆ, ๋ถ์ ๋ฒํธ ๊ทธ๋ฆฌ๊ณ ๋ถ์ ์ด๋ฆ์ ์กฐํํ ๊ฒฐ๊ณผ์
๋๋ค.
SELECT e.employee_id , CONCAT(e.first_name, e.last_name) AS name , d.department_id , d.department_name FROM `HR.employees` AS e LEFT JOIN `HR.departments` AS d ON e.department_id = d.department_id;

ย
8.2.1. ์ ์์ INNER JOIN์ผ๋ก ๋ ํ
์ด๋ธ์ ๊ฒฐํฉํ์ ๋, ์ฌ์ ๋ฒํธ 178๋ฒ์ ๋ ์ฝ๋๊ฐ ์กฐํ๋์ง ์์์์ ํ์ธํ์ต๋๋ค. ๊ธฐ์กด์ โemployeesโ ํ
์ด๋ธ์์ ์ฌ์๋ฒํธ 178๋ฒ์ ๋ ์ฝ๋๋ โdepartment_idโ๊ฐ
NULL
๊ฐ์ด๊ธฐ ๋๋ฌธ์ โemployeesโ ํ
์ด๋ธ๊ณผ โdepartmentsโ ํ
์ด๋ธ์ โdepartment_idโ๋ก ์ฐ๊ฒฐ ์ ์กฐ์ธ ์กฐ๊ฑด์ ๋ง์กฑํ์ง ์์ ๊ฒฐ๊ณผ์ ํฌํจ๋์ง ์์์ต๋๋ค. SELECT employee_id , CONCAT(first_name, last_name) AS name , department_id FROM `HR.employees` WHERE employee_id = 178;

ย
ํ์ง๋ง LEFT JOIN์ ์ฌ์ฉํ๋ฉด ์ผ์ชฝ ํ
์ด๋ธ์ ํน์ ๋ ์ฝ๋์ ๋ํด ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์์ ์ผ์นํ๋ ๋ ์ฝ๋๊ฐ ์์ ๋, ํด๋น ๋ ์ฝ๋๋ ๊ฒฐ๊ณผ ์ฌ์ ํ ํฌํจ๋๋ฉฐ LEFT JOIN ๋ ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์ ๋ชจ๋ ์ปฌ๋ผ ๊ฐ์
NULL
๋ก ํ์๋ฉ๋๋ค. ์ด๋ฌํ ๋ฐฉ์์ผ๋ก LEFT JOIN์ ๋๋ฝ๋ ๋ฐ์ดํฐ๋ ์ผ์นํ์ง ์๋ ๋ ์ฝ๋๋ฅผ ์ฐพ๋ ๋ฐ ์ ์ฉํฉ๋๋ค. ๊ฒฐ๊ณผ์์ NULL
๊ฐ์ ํ์ธํ์ฌ ์ด๋ค ๋ ์ฝ๋๊ฐ ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์ ์๋์ง ์๋ณํ ์ ์์ต๋๋ค.SELECT e.employee_id , CONCAT(e.first_name, e.last_name) AS name , d.department_id , d.department_name FROM `HR.employees` AS e LEFT JOIN `HR.departments` AS d ON e.department_id = d.department_id WHERE e.employee_id > 170;

ย
8.2.3. RIGHT JOIN
RIGHT JOIN, ๋๋ RIGHT OUTER JOIN์ ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์ ๋ชจ๋ ๋ ์ฝ๋์ ์ผ์ชฝ ํ
์ด๋ธ์์ ์ผ์นํ๋ ๋ ์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค. ์ผ์นํ๋ ์ผ์ชฝ ํ
์ด๋ธ์ ๋ ์ฝ๋๊ฐ ์๋ ๊ฒฝ์ฐ, ๊ฒฐ๊ณผ์๋
NULL
๊ฐ์ด ํฌํจ๋ฉ๋๋ค.LEFT JOIN ๊ณผ๋ ๋ฐ๋๋ก RIGHT JOIN์ ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์ ๋ชจ๋ ๋ ์ฝ๋๋ฅผ ํฌํจํ ๊ฒฐ๊ณผ๋ฅผ ์ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
ย

# ANSI SQL JOIN SELECT * FROM Table1 RIGHT [OUTER] JOIN Table2 ON Table1.column = Table2.column;
RIGHT JOIN์ ํ์ฉํ๋ฉด ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์ ํน์ ๋ ์ฝ๋๊ฐ ์ผ์ชฝ ํ
์ด๋ธ์์ ์ผ์นํ๋ ํญ๋ชฉ์ ๊ฐ์ง ์์ ๊ฒฝ์ฐ์๋ ๊ทธ ๋ ์ฝ๋๋ ๋ฐํ ๊ฒฐ๊ณผ์ ํฌํจ๋ฉ๋๋ค. ์ด๋ RIGHT JOIN ๋ ์ผ์ชฝ ํ
์ด๋ธ์ ๊ด๋ จ ์ปฌ๋ผ ๊ฐ๋ค์
NULL
๋ก ๋ํ๋ฉ๋๋ค.ย
HR ๋ฐ์ดํฐ ์
์ โemployeesโ ํ
์ด๋ธ๊ณผ โdepartmentโ ํ
์ด๋ธ์ ์ฌ์ฉํ์ฌ RIGHT JOIN ์์
์ ์งํํด ๋ณด๊ฒ ์ต๋๋ค. ํด๋น ์์์์๋ โemployeesโ ํ
์ด๋ธ์ FK์ธ โdepartment_idโ์ โdepartmentsโ ํ
์ด๋ธ์ PK์ธ โdepartment_idโ๋ฅผ ์ด์ฉํ์ฌ ๋ ํ
์ด๋ธ์ ๊ฒฐํฉํฉ๋๋ค. ์ด๋, โemployeesโ ํ
์ด๋ธ์ ์ผ์ชฝ, โdepartmentsโ ํ
์ด๋ธ์ ์ค๋ฅธ์ชฝ ์์น์ ๋๊ณ RIGHT JOIN ์ฐ์ฐ์ ์ํํด ๋ณด๊ฒ ์ต๋๋ค.
SELECT e.employee_id , e.department_id AS e_department_id , d.department_id AS d_department_id , d.department_name FROM `HR.employees` AS e RIGHT JOIN `HR.departments` AS d ON e.department_id = d.department_id ORDER BY e.department_id;

๊ฒฐ๊ณผ ํ
์ด๋ธ์ โd_department_idโ ์ปฌ๋ผ์ 1ํ๋ถํฐ 16ํ๊น์ง์ ๊ฐ๋ค์ ์ผ์ชฝ์ ์์นํ โemployeesโ ํ
์ด๋ธ์ โdepartment_idโ์๋ ์กด์ฌํ์ง ์๋ ๊ฐ์
๋๋ค. ๋ฐ๋ผ์ departments ํ
์ด๋ธ์ ๋ชจ๋ ํญ๋ชฉ๋ค์ ์กฐํ๋์ง๋ง, RIGHT JOIN ๋ โemployeesโ ํ
์ด๋ธ์ โemployee_idโ์ โe_department_idโ๋
NULL
๊ฐ์ด ๋ฐํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.ย
8.2.4. FULL OUTER JOIN
FULL OUTER JOIN์ ๋ ํ
์ด๋ธ ์ค ํ๋๋ผ๋ ์ผ์นํ๋ ๋ชจ๋ ํ์ ํฌํจํ๋ ๊ฒฐ๊ณผ ์งํฉ์ ๋ฐํํฉ๋๋ค. ๋ ํ
์ด๋ธ์์ ์ผ์นํ์ง ์๋ ์ด์
NULL
๊ฐ์ผ๋ก ์ฑ์์ง๋๋ค.์์ ์ค๋ช
ํ LEFT JOIN๊ณผ RIGHT JOIN์ ํฉ์น ๊ฒ๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.

# ANSI SQL JOIN SELECT * FROM Table1 FULL [OUTER] JOIN Table2 ON Table1.column = Table2.column;
ANSI SQL JOIN ๋ฌธ๋ฒ์์ FULL OUTER JOIN ์ OUTER๋ฅผ ์๋ตํ๊ณ FULL JOIN์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
ย
โHRโ ๋ฐ์ดํฐ์
์ ์ฌ์ฉํด์ ์ค์ตํด ๋ณด๊ฒ ์ต๋๋ค. โemployeesโ ํ
์ด๋ธ๊ณผ โdepartmentsโ ํ
์ด๋ธ์ FULL OUTER JOIN ํด์ ๋ชจ๋ ๋ถ์์ ๋ชจ๋ ์ง์์ ์กฐํํ๊ฒ ์ต๋๋ค. ๋จผ์ , โemployeesโ ๋ฐ์ดํฐ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
SELECT employee_id , first_name , last_name , department_id FROM `HR.employees` WHERE department_id IS NULL;

โemployeesโ ํ
์ด๋ธ ์ค ๋ถ์ ID (โdepartment_idโ) ์ ๋ณด๊ฐ ์๋ ๋ฐ์ดํฐ 1๊ฐ ํ์ด ์์ต๋๋ค.
ย
JOIN ์ฐ์ฐ์ ์ํํ๊ธฐ ์ ์ โemployeesโํ
์ด๋ธ์ ๊ณ ์ ํ โdepartment_idโ์ โdepartmentsโํ
์ด๋ธ์ ๊ณ ์ ํ โdepartment_idโ๋ฅผ ๋น๊ตํด ๋ณด๊ฒ ์ต๋๋ค. โdepartmentsโํ
์ด๋ธ์ โdepartment_idโ ์ค โemployeesโํ
์ด๋ธ์ โdepartment_idโ ์ ์ผ์นํ์ง ์๋ ๊ฐ์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
# ์ผ์ชฝ ๊ฒฐ๊ณผ ํ ์ด๋ธ SELECT DISTINCT department_id FROM `HR.employees` ORDER BY 1; # ์ค๋ฅธ์ชฝ ๊ฒฐ๊ณผ ํ ์ด๋ธ SELECT DISTINCT department_id FROM `HR.departments` ORDER BY 1;


ย
โdepartmentsโํ
์ด๋ธ์ PK์ธ โdepartment_idโ์ โemployeesโํ
์ด๋ธ์ FK์ธ โdepartment_idโ๋ฅผ ๊ธฐ์ค์ผ๋ก FULL OUTER JOIN ํ๋ฉด ์๋์ ๊ฐ์ ํ
์ด๋ธ์ ๋ฐํํฉ๋๋ค.
# ANSI SQL JOIN SELECT e.employee_id , e.first_name , e.last_name , d.department_id FROM `HR.employees` AS e FULL JOIN `HR.departments` AS d ON e.department_id = d.department_id;

๋ฐ์ดํฐ๋ฅผ ์ดํด๋ณด๋ฉด์ ํ์ธํ๋ ๊ฒ๊ณผ ๊ฐ์ด โemployeesโํ
์ด๋ธ์์ โdepartment_idโ๊ฐ
NULL
์ธ ํ์ด ๊ฒฐ๊ณผ ์งํฉ์ ํฌํจ๋์๊ณ , โemployeesโํ
์ด๋ธ์ โdepartment_idโ์ ์ผ์นํ์ง ์๋ โdepartmentsโํ
์ด๋ธ์ โdepartment_idโํ์ โemployee_idโ, โfirst_nameโ, โlast_nameโ์ด์ ๊ฐ์ด NULL
๊ฐ์ผ๋ก ์ฑ์์ก์ต๋๋ค.ย
์์ FULL OUTER JOIN ํ ๊ฒฐ๊ณผ ํ
์ด๋ธ์ LEFT JOIN ๊ณผ RIGHT JOIN์ ํฉ์น ๊ฒฐ๊ณผ ํ
์ด๋ธ๊ณผ ๋น๊ตํด ๋ณด๊ฒ ์ต๋๋ค.
(SELECT e.employee_id , e.first_name , e.last_name , d.department_id FROM `HR.employees` AS e LEFT JOIN `HR.departments` AS d ON e.department_id = d.department_id) UNION DISTINCT (SELECT e.employee_id , e.first_name , e.last_name , d.department_id FROM `HR.employees` AS e RIGHT JOIN `HR.departments` AS d ON e.department_id = d.department_id);

UNION ์ฐ์ฐ์ผ๋ก ์ธํด ๋ ํ
์ด๋ธ์ด ๋ค๋ฅด๊ฒ ์ ๋ ฌ๋์ด ์์ง๋ง, ๊ฒฐ๊ณผ ํ
์ด๋ธ ํ์ ์๋ฅผ ๋ณด๋ฉด ๊ฐ์ ๊ฒฐ๊ณผ ํ
์ด๋ธ์ ๋ฐํํ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
Oracle SQL JOIN ๋ฌธ๋ฒ์ FULL OUTER JOIN์ ์ง์ํ์ง ์์ต๋๋ค. ๋ํ, MySQL DB๋ ANSI JOIN ๋ฌธ๋ฒ์ธ FULL OUTER JOIN์ ์ง์ํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์, LEFT JOIN๊ณผ RIGHT JOIN ๊ฒฐ๊ณผ๋ฅผ UNION DISTINCT ์ฐ์ฐํ์ฌ ๊ตฌํํฉ๋๋ค.
ย
8.2.5. CROSS JOIN
CROSS JOIN์ Cartesian Product๋ผ๊ณ ๋ ํ๋ฉฐ, ๋ ๊ฐ์ ํ
์ด๋ธ์ ๊ฒฐํฉํ ๋ ๋ชจ๋ ํ์ ์กฐํฉ์ ๋ฐํํ๋ JOIN ์ฐ์ฐ์
๋๋ค.

CROSS JOIN์ ๊ฐ ํ์ด ๋ค๋ฅธ ๋ชจ๋ ํ๊ณผ ๊ฒฐํฉ๋ฉ๋๋ค. JOIN์ ์ํํ๋ ๋ ํ
์ด๋ธ ํ์ ์๋ฅผ ๊ฐ๊ฐ m๊ณผ n์ด๋ผ๊ณ ํ์ ๋, ์ถ๋ ฅ๋๋ ๊ฒฐ๊ณผ ํ์ ์๋ m x n๊ณผ ๊ฐ์ต๋๋ค. CROSS JOIN์ ๋ค๋ฅธ JOIN ์ฐ์ฐ๊ณผ ๋ค๋ฅด๊ฒ JOIN ์กฐ๊ฑด์ ์
๋ ฅํ์ง ์์ต๋๋ค.
# ANSI SQL JOIN SELECT * FROM Table1 CROSS JOIN Table2; # ORACLE SQL JOIN SELECT * FROM Table1, Table2;
CROSS JOIN์ ๊ฒฐ๊ณผ ์งํฉ์ด ํฌ๊ณ ์ค๋ณต ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ ์ ์์ผ๋ฏ๋ก ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
WHERE
์ ์์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํด์ JOIN ์ฐ์ฐ๋์ ์ค์ผ ์ ์์ต๋๋ค.ย
โHRโ ๋ฐ์ดํฐ์
์ โlocationsโํ
์ด๋ธ๊ณผ โjobsโํ
์ด๋ธ์ CROSS JOIN ํ์ฌ ๋ชจ๋ ์ง์ญ์ ๋ชจ๋ ์ง์
์ ๋ํ ์กฐํฉ์ ์ถ๋ ฅํด ๋ณด๊ฒ ์ต๋๋ค. ๋จผ์ , โlocationsโํ
์ด๋ธ๊ณผ โjobsโํ
์ด๋ธ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. โlocationsโํ
์ด๋ธ์ 23๊ฐ์ ํ, โjobsโํ
์ด๋ธ์ 19๊ฐ์ ํ์ ๊ฐ๊ณ ์์ต๋๋ค.
# ์ผ์ชฝ ๊ฒฐ๊ณผ ํ ์ด๋ธ SELECT location_id , street_address , city FROM `HR.locations`; # ์ค๋ฅธ์ชฝ ๊ฒฐ๊ณผ ํ ์ด๋ธ SELECT job_id , job_title FROM `HR.jobs`;


โlocationsโํ
์ด๋ธ๊ณผ โjobsโํ
์ด๋ธ์ CROSS JOINํ๋ฉด 23 x 19 = 437๊ฐ ํ์ ๊ฐ์ง ์งํฉ์ ๋ฐํํฉ๋๋ค.
# ANSI SQL JOIN SELECT l.city , j.job_title FROM `HR.locations` AS l CROSS JOIN `HR.jobs` AS j; # ORACLE SQL JOIN SELECT l.city , j.job_title FROM `HR.locations` AS l, `HR.jobs` AS j;

์์ ์์์ ๊ฐ์ด CROSS JOIN์ ๋ ํ
์ด๋ธ ์ฌ์ด์ ๋ชจ๋ ํ์ ์กฐํฉ์ ์ถ๋ ฅํ๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ JOIN์ ๋นํด ๊ฒฐ๊ณผ ์งํฉ์ด ๋งค์ฐ ํฌ๊ธฐ ๋๋ฌธ์ ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
ย
๋ค์์ผ๋ก โjobsโํ
์ด๋ธ์ โmax_salaryโ์ปฌ๋ผ์ ์ฌ์ฉํ์ฌ ์ต๋ ๊ธ์ฌ๊ฐ 10,000 ์ด์์ธ ์ง์
๊ณผ ๋ชจ๋ ์ง์ญ์ ๋ํ ์กฐํฉ์ ๊ตฌํด ๋ณด๊ฒ ์ต๋๋ค. โmax_salaryโ๊ฐ 10,000 ์ด์์ธ ์ง์
์ 10๊ฐ์ธ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
SELECT COUNT(job_title) FROM `HR.jobs` WHERE max_salary >= 10000;

ย
์ถ๊ฐ๋ก โcountriesโํ
์ด๋ธ์ ๊ตญ๊ฐ๋ช
์ ํจ๊ป ์กฐํํ๊ณ , ๊ตญ๊ฐ๋ช
์ผ๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌํ์ต๋๋ค.
# ANSI SQL JOIN SELECT c.country_name , l.city , j.job_title FROM `HR.locations` AS l JOIN `HR.countries` AS c ON l.country_id = c.country_id CROSS JOIN `HR.jobs` AS j WHERE j.max_salary >= 10000 ORDER BY c.country_name DESC; # ORACLE SQL JOIN SELECT c.country_name , l.city , j.job_title FROM `HR.locations` AS l, `HR.countries` AS c, `HR.jobs` AS j WHERE l.country_id = c.country_id AND j.max_salary >= 10000 ORDER BY c.country_name DESC;

โmax_salaryโ๊ฐ 10,000 ์ด์์ธ โjobsโํ
์ด๋ธ์ 10๊ฐ์ ํ์ ๊ฐ๊ณ , โlocationsโํ
์ด๋ธ๊ณผ โcountriesโํ
์ด๋ธ์ INNER JOIN ํ ํ
์ด๋ธ์ 23๊ฐ์ ํ์ ๊ฐ์ง๋ฏ๋ก 10 x 23 = 230๊ฐ์ ํ์ ๊ฐ์ง ํ
์ด๋ธ์ ๋ฐํํฉ๋๋ค. ์ด์ ๊ฐ์ด
WHERE
์ ์์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ์ฌ JOIN ์ฐ์ฐ ํฌ๊ธฐ๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.ย
8.2.6. SELF JOIN
SELF JOIN์ ๋์ผํ ํ
์ด๋ธ ์ฌ์ด์ JOIN ์ฐ์ฐ์
๋๋ค. ๋ฐ๋ผ์ ๋ค๋ฅธ JOIN ์ฐ์ฐ๊ณผ ๋ฌ๋ฆฌ
FROM
์ ์ ๋์ผํ ํ
์ด๋ธ์ด 2๋ฒ ์ด์ ์ฌ์ฉ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก SELF JOIN์ ํ
์ด๋ธ ๋ด ๋ค๋ฅธ ํ๊ณผ์ ๊ด๊ณ๋ฅผ ์ฐพ๊ฑฐ๋ ๊ณ์ธต ๊ตฌ์กฐ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค. SELF JOIN์ ๋์ผํ ํ
์ด๋ธ์ ์ฌ๋ฌ ๋ฒ ์ฐธ์กฐํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ฐ๋์ ํ
์ด๋ธ ๋ณ์นญ(ALIAS)๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.# ANSI SQL JOIN SELECT * FROM Table1 AS t1 [INNER|LEFT|RIGHT] JOIN Table2 AS t2 ON t1.column1 = t2.column2;
โHRโ ๋ฐ์ดํฐ์
์ โemployeesโํ
์ด๋ธ์ ์ฌ์ฉํ์ฌ SELF JOIN์ ์ค์ตํด ๋ณด๊ฒ ์ต๋๋ค. ๋จผ์ , โemployeesโํ
์ด๋ธ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
SELECT employee_id , first_name , email , department_id , manager_id FROM `HR.employees`;

โemployeesโํ
์ด๋ธ์ 107๋ช
์ ์ง์์ ๋ํ ์ ๋ณด๋ฅผ ๊ฐ๋ ํ
์ด๋ธ์
๋๋ค. ์ด ํ
์ด๋ธ์ ๊ฐ ์ง์์ ๊ด๋ฆฌํ๋ ์์ฌ์ โemployee_idโ(โmanager_idโ)๋ฅผ ๊ฐ์ต๋๋ค. SELF JOIN์ ์ฌ์ฉํ์ฌ ์ง์ ์ ๋ณด์ ํจ๊ป ๊ด๋ฆฌ์๋ช
์ ๋ฐํํด ๋ณด๊ฒ ์ต๋๋ค. ์ต์์ ๊ด๋ฆฌ์์ ๊ฒฝ์ฐ, โmanager_idโ์ด์ด
NULL
๊ฐ์ ๊ฐ๊ธฐ ๋๋ฌธ์ LEFT JOIN์ ์ฌ์ฉํ๊ฒ ์ต๋๋ค.# ANSI SQL JOIN SELECT e.employee_id , e.first_name , e.email , e.department_id , m.employee_id AS manager_id , m.first_name AS manager_name FROM `HR.employees` AS e LEFT JOIN `HR.employees` AS m ON e.manager_id = m.employee_id;

SELF JOIN์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ณต์กํ ๊ด๊ณ์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๋ค๋ฃฐ ๋ ์ ์ฉํฉ๋๋ค. ํนํ ์กฐ์ง ๊ตฌ์กฐ, ์ ํ ๋ฒ์ฃผ, ๊ณ์ธต์ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๊ด๋ จ๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.