편집 요약 없음 |
편집 요약 없음 |
||
1번째 줄: | 1번째 줄: | ||
=== Oracle 테이블 조인 (Table Join) === | |||
{{요점 | |||
|내용=조인이란? | |||
> 여러 테이블에서 관련된 데이터를 **하나의 결과로 결합**해서 보여주는 SQL 기능입니다. | > 여러 테이블에서 관련된 데이터를 **하나의 결과로 결합**해서 보여주는 SQL 기능입니다. | ||
11번째 줄: | 8번째 줄: | ||
예: 직원 정보는 `EMPLOYEES`, 부서 정보는 `DEPARTMENTS`에 있을 때 | 예: 직원 정보는 `EMPLOYEES`, 부서 정보는 `DEPARTMENTS`에 있을 때 | ||
👉 직원 이름 + 부서 이름을 함께 보여주고 싶을 때 조인을 사용합니다. | 👉 직원 이름 + 부서 이름을 함께 보여주고 싶을 때 조인을 사용합니다. | ||
}} | |||
--- | --- | ||
===예제 테이블=== | |||
<source lang=sql> | |||
-- EMPLOYEES 테이블 | -- EMPLOYEES 테이블 | ||
| EMP_ID | NAME | DEPT_ID | | | EMP_ID | NAME | DEPT_ID | | ||
30번째 줄: | 27번째 줄: | ||
| 20 | IT | | | 20 | IT | | ||
| 30 | Marketing | | | 30 | Marketing | | ||
</source> | |||
--- | --- | ||
54번째 줄: | 52번째 줄: | ||
## 📘 INNER JOIN | ## 📘 INNER JOIN | ||
<source lang=sql> | |||
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | ||
FROM EMPLOYEES E | FROM EMPLOYEES E | ||
INNER JOIN DEPARTMENTS D | INNER JOIN DEPARTMENTS D | ||
ON E.DEPT_ID = D.DEPT_ID; | ON E.DEPT_ID = D.DEPT_ID; | ||
</source> | |||
{| class="wikitable" | {| class="wikitable" | ||
! EMP_ID || NAME || DEPT_NAME | |||
|- | |||
| - | | 101 || Alice || HR | ||
| 101 | |- | ||
| - | | 102 || Bob || IT | ||
| 102 | |- | ||
| - | | 103 || Charlie || HR | ||
| 103 | |} | ||
| } | |||
--- | --- | ||
## 📘 LEFT OUTER JOIN | ## 📘 LEFT OUTER JOIN | ||
<source lang=sql> | |||
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | ||
FROM EMPLOYEES E | FROM EMPLOYEES E | ||
LEFT OUTER JOIN DEPARTMENTS D | LEFT OUTER JOIN DEPARTMENTS D | ||
ON E.DEPT_ID = D.DEPT_ID; | ON E.DEPT_ID = D.DEPT_ID; | ||
</source> | |||
* `EMPLOYEES`의 모든 직원은 다 나오고, | * `EMPLOYEES`의 모든 직원은 다 나오고, | ||
89번째 줄: | 85번째 줄: | ||
## 📘 RIGHT OUTER JOIN | ## 📘 RIGHT OUTER JOIN | ||
<source lang=sql> | |||
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | ||
FROM EMPLOYEES E | FROM EMPLOYEES E | ||
RIGHT OUTER JOIN DEPARTMENTS D | RIGHT OUTER JOIN DEPARTMENTS D | ||
ON E.DEPT_ID = D.DEPT_ID; | ON E.DEPT_ID = D.DEPT_ID; | ||
</source> | |||
* `DEPARTMENTS`의 모든 부서는 다 나오고, | * `DEPARTMENTS`의 모든 부서는 다 나오고, | ||
104번째 줄: | 99번째 줄: | ||
## 📘 FULL OUTER JOIN | ## 📘 FULL OUTER JOIN | ||
<source lang=sql> | |||
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | ||
FROM EMPLOYEES E | FROM EMPLOYEES E | ||
FULL OUTER JOIN DEPARTMENTS D | FULL OUTER JOIN DEPARTMENTS D | ||
ON E.DEPT_ID = D.DEPT_ID; | ON E.DEPT_ID = D.DEPT_ID; | ||
</source> | |||
* `EMPLOYEES`, `DEPARTMENTS` 둘 다 포함 | * `EMPLOYEES`, `DEPARTMENTS` 둘 다 포함 | ||
118번째 줄: | 113번째 줄: | ||
## 📘 CARTESIAN JOIN (CROSS JOIN) | ## 📘 CARTESIAN JOIN (CROSS JOIN) | ||
<source lang=sql> | |||
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | SELECT E.EMP_ID, E.NAME, D.DEPT_NAME | ||
FROM EMPLOYEES E | FROM EMPLOYEES E | ||
CROSS JOIN DEPARTMENTS D; | CROSS JOIN DEPARTMENTS D; | ||
</source> | |||
* 조인 조건 없이 **모든 행을 조합** | * 조인 조건 없이 **모든 행을 조합** | ||
128번째 줄: | 123번째 줄: | ||
{| class="wikitable" | {| class="wikitable" | ||
! EMP_ID || NAME || DEPT_NAME | |||
|- | |||
| - | | 101 || Alice || HR | ||
| 101 | |- | ||
| - | | 101 || Alice || IT | ||
| 101 | |- | ||
| - | | 101 || Alice || Marketing | ||
| 101 | |- | ||
| - | | 102 || Bob || HR | ||
| 102 | |- | ||
| | | 102 || Bob || IT | ||
| ... | |- | ||
| } | | ... || ... || ... | ||
|} | |||
> ❗ 주의: **WHERE 조건 없이 CROSS JOIN을 쓰면 큰 결과가 나올 수 있어 조심해야 합니다.** | > ❗ 주의: **WHERE 조건 없이 CROSS JOIN을 쓰면 큰 결과가 나올 수 있어 조심해야 합니다.** | ||
148번째 줄: | 144번째 줄: | ||
## 📘 ANTI JOIN (조건에 부합하지 않는 데이터만) | ## 📘 ANTI JOIN (조건에 부합하지 않는 데이터만) | ||
<source lang=sql> | |||
SELECT * | SELECT * | ||
FROM DEPARTMENTS D | FROM DEPARTMENTS D | ||
154번째 줄: | 150번째 줄: | ||
SELECT 1 FROM EMPLOYEES E WHERE E.DEPT_ID = D.DEPT_ID | SELECT 1 FROM EMPLOYEES E WHERE E.DEPT_ID = D.DEPT_ID | ||
); | ); | ||
</source> | |||
* **직원이 없는 부서만 조회**하는 예제입니다. | * **직원이 없는 부서만 조회**하는 예제입니다. | ||
{| class="wikitable" | {| class="wikitable" | ||
! DEPT_ID || DEPT_NAME | |||
|- | |||
| - | | 30 || Marketing | ||
| 30 | |} | ||
| } | | | | | ||
> ✅ 실무에서 **특정 값이 존재하지 않는 경우**를 찾을 때 많이 사용합니다. | > ✅ 실무에서 **특정 값이 존재하지 않는 경우**를 찾을 때 많이 사용합니다. | ||
170번째 줄: | 165번째 줄: | ||
## 📌 마무리 요약 표 | ## 📌 마무리 요약 표 | ||
{| class="wikitable" | {| class="wikitable" | ||
! 조인 종류 || 대표 SQL 구문 || 출력 대상 | |||
|- | |||
| - | | INNER JOIN || A INNER JOIN B ON 조건 || A와 B 모두 조건에 맞는 데이터만 | ||
| INNER JOIN | |- | ||
| - | | LEFT OUTER JOIN || A LEFT OUTER JOIN B ON 조건 || A는 모두, B는 맞는 것만 | ||
| LEFT OUTER JOIN | |- | ||
| - | | RIGHT OUTER JOIN || A RIGHT OUTER JOIN B ON 조건 || B는 모두, A는 맞는 것만 | ||
| RIGHT OUTER JOIN | |- | ||
| - | | FULL OUTER JOIN || A FULL OUTER JOIN B ON 조건 || A와 B 모두 포함 | ||
| FULL OUTER JOIN | |- | ||
| - | | CROSS JOIN || A CROSS JOIN B || 모든 조합 (곱집합) | ||
| CROSS JOIN | |- | ||
| - | | ANTI JOIN || WHERE NOT EXISTS (서브쿼리) || 조건에 부합하지 않는 데이터 | ||
| ANTI JOIN | |} | ||
| } | | | | | | | ||
--- | --- |
2025년 5월 14일 (수) 01:13 판
Oracle 테이블 조인 (Table Join)
menu_book 조인이란?
> 여러 테이블에서 관련된 데이터를 **하나의 결과로 결합**해서 보여주는 SQL 기능입니다.
예: 직원 정보는 `EMPLOYEES`, 부서 정보는 `DEPARTMENTS`에 있을 때
👉 직원 이름 + 부서 이름을 함께 보여주고 싶을 때 조인을 사용합니다.---
예제 테이블
-- EMPLOYEES 테이블 | EMP_ID | NAME | DEPT_ID | |--------|---------|---------| | 101 | Alice | 10 | | 102 | Bob | 20 | | 103 | Charlie | 10 | -- DEPARTMENTS 테이블 | DEPT_ID | DEPT_NAME | |---------|------------| | 10 | HR | | 20 | IT | | 30 | Marketing |
---
- 📌 조인 종류 요약
조인 종류 | 설명 |
---|---|
INNER JOIN | 두 테이블에서 일치하는 값이 있는 행만 보여줌 |
LEFT OUTER JOIN | 왼쪽 테이블은 무조건 모두 출력, 오른쪽에 일치하는 값이 없으면 NULL |
RIGHT OUTER JOIN | 오른쪽 테이블은 무조건 모두 출력, 왼쪽에 일치하는 값이 없으면 NULL |
FULL OUTER JOIN | 양쪽 테이블을 모두 포함, 일치하지 않으면 NULL |
CROSS JOIN (카테시안 조인) | 두 테이블의 모든 행 조합을 출력 (곱집합) |
ANTI JOIN | 조건에 맞지 않는 행만 보여줌 (EXISTS가 아닌 NOT EXISTS 조건) |
- 📘 INNER JOIN
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME FROM EMPLOYEES E INNER JOIN DEPARTMENTS D ON E.DEPT_ID = D.DEPT_ID;
EMP_ID | NAME | DEPT_NAME |
---|---|---|
101 | Alice | HR |
102 | Bob | IT |
103 | Charlie | HR |
---
- 📘 LEFT OUTER JOIN
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME FROM EMPLOYEES E LEFT OUTER JOIN DEPARTMENTS D ON E.DEPT_ID = D.DEPT_ID;
- `EMPLOYEES`의 모든 직원은 다 나오고,
- 일치하지 않는 부서가 있으면 `DEPT_NAME`은 NULL
---
- 📘 RIGHT OUTER JOIN
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME FROM EMPLOYEES E RIGHT OUTER JOIN DEPARTMENTS D ON E.DEPT_ID = D.DEPT_ID;
- `DEPARTMENTS`의 모든 부서는 다 나오고,
- 직원이 없는 부서는 `EMP_ID`, `NAME`이 NULL
---
- 📘 FULL OUTER JOIN
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME FROM EMPLOYEES E FULL OUTER JOIN DEPARTMENTS D ON E.DEPT_ID = D.DEPT_ID;
- `EMPLOYEES`, `DEPARTMENTS` 둘 다 포함
- 한쪽에만 데이터가 있으면 다른 쪽은 NULL
---
- 📘 CARTESIAN JOIN (CROSS JOIN)
SELECT E.EMP_ID, E.NAME, D.DEPT_NAME FROM EMPLOYEES E CROSS JOIN DEPARTMENTS D;
- 조인 조건 없이 **모든 행을 조합**
- EMPLOYEES가 3행, DEPARTMENTS가 3행이면 → 결과는 9행
EMP_ID | NAME | DEPT_NAME |
---|---|---|
101 | Alice | HR |
101 | Alice | IT |
101 | Alice | Marketing |
102 | Bob | HR |
102 | Bob | IT |
... | ... | ... |
> ❗ 주의: **WHERE 조건 없이 CROSS JOIN을 쓰면 큰 결과가 나올 수 있어 조심해야 합니다.**
---
- 📘 ANTI JOIN (조건에 부합하지 않는 데이터만)
SELECT * FROM DEPARTMENTS D WHERE NOT EXISTS ( SELECT 1 FROM EMPLOYEES E WHERE E.DEPT_ID = D.DEPT_ID );
- **직원이 없는 부서만 조회**하는 예제입니다.
DEPT_ID | DEPT_NAME |
---|---|
30 | Marketing |
| | |
> ✅ 실무에서 **특정 값이 존재하지 않는 경우**를 찾을 때 많이 사용합니다.
---
- 📌 마무리 요약 표
조인 종류 | 대표 SQL 구문 | 출력 대상 |
---|---|---|
INNER JOIN | A INNER JOIN B ON 조건 | A와 B 모두 조건에 맞는 데이터만 |
LEFT OUTER JOIN | A LEFT OUTER JOIN B ON 조건 | A는 모두, B는 맞는 것만 |
RIGHT OUTER JOIN | A RIGHT OUTER JOIN B ON 조건 | B는 모두, A는 맞는 것만 |
FULL OUTER JOIN | A FULL OUTER JOIN B ON 조건 | A와 B 모두 포함 |
CROSS JOIN | A CROSS JOIN B | 모든 조합 (곱집합) |
ANTI JOIN | WHERE NOT EXISTS (서브쿼리) | 조건에 부합하지 않는 데이터 |
| | | | |
---