SQL 통한 Database 관리

where not exists

JBS 12 2024. 8. 20. 19:04

`WHERE NOT EXISTS`는 SQL에서 특정 조건에 해당하는 데이터가 **존재하지 않을 때** 참(`TRUE`)이 되는 조건을 나타냅니다. 주로 서브쿼리와 함께 사용되어, 특정 조건을 만족하는 데이터가 존재하지 않을 경우에만 결과를 반환하게 합니다.

### `EXISTS`와 `NOT EXISTS` 개념

- **`EXISTS`**: 서브쿼리가 하나 이상의 레코드를 반환하면 `TRUE`가 됩니다.
- **`NOT EXISTS`**: 서브쿼리가 **아무런** 레코드도 반환하지 않을 때 `TRUE`가 됩니다.

### `WHERE NOT EXISTS`의 동작 방식

1. **서브쿼리 실행**:
   - `NOT EXISTS` 절 내부의 서브쿼리가 실행됩니다.
   - 서브쿼리는 일반적으로 `SELECT` 문을 포함하며, 조건에 맞는 레코드를 검색합니다.

2. **서브쿼리 결과 확인**:
   - 서브쿼리가 아무런 결과를 반환하지 않으면(즉, 서브쿼리의 조건을 만족하는 레코드가 없으면) `NOT EXISTS`가 `TRUE`가 됩니다.
   - 서브쿼리가 결과를 반환하면 `NOT EXISTS`가 `FALSE`가 됩니다.

3. **메인 쿼리에서 조건 적용**:
   - 메인 쿼리에서 `NOT EXISTS`가 `TRUE`인 경우에만 레코드를 선택합니다.

### 예제

다음은 `TBL1`에 있는 `ID`가 `TBL2`에 없는 경우에 해당 `ID`를 찾는 예제입니다.

```sql
SELECT A.ID
FROM TBL1 A
WHERE NOT EXISTS (SELECT 1 FROM TBL2 B WHERE A.ID = B.ID);
```

- **서브쿼리**: `SELECT 1 FROM TBL2 B WHERE A.ID = B.ID`
  - `TBL1`의 `ID` 값과 `TBL2`의 `ID` 값을 비교합니다.
  - `TBL2`에 `TBL1.ID`와 동일한 값이 있으면, 서브쿼리는 값을 반환합니다.

- **`NOT EXISTS`**:
  - `TBL2`에 `TBL1.ID`와 동일한 값이 없을 경우, 서브쿼리는 값을 반환하지 않으므로, `NOT EXISTS` 조건이 `TRUE`가 됩니다.
  - 메인 쿼리는 이러한 `ID` 값을 선택합니다.

### 시각적인 예제

**TBL1**

| ID  |
|-----|
| 1   |
| 2   |
| 3   |

**TBL2**

| ID  |
|-----|
| 1   |
| 3   |
| 4   |

- `ID = 2`는 `TBL2`에 존재하지 않으므로, `NOT EXISTS` 조건이 `TRUE`가 됩니다.
- 따라서, 최종 결과는 다음과 같습니다:

**결과**:

| ID  |
|-----|
| 2   |

### 사용 사례

1. **두 테이블 간의 차집합 찾기**: 한 테이블에만 존재하는 데이터를 찾기 위해 사용됩니다.
2. **중복 데이터 필터링**: 특정 조건을 만족하지 않는 데이터만을 선택하여 결과를 제한할 때 사용합니다.
3. **데이터 무결성 확인**: 다른 테이블에 종속되지 않은 데이터를 식별하여 삭제 또는 업데이트 시 조치를 취할 수 있습니다.

### 요약

`WHERE NOT EXISTS`는 주로 서브쿼리와 함께 사용되며, 서브쿼리가 결과를 반환하지 않는 경우에만 참이 됩니다. 이를 통해 특정 조건에 맞지 않는 데이터를 필터링할 수 있습니다.

그럼 값은 따로 안 나오고 true false만 나오는거니?


`WHERE NOT EXISTS` 절 자체는 `TRUE` 또는 `FALSE` 값을 반환하는 논리적 조건입니다. 이 조건이 메인 쿼리의 `WHERE` 절에 사용되면, 해당 조건이 `TRUE`인 레코드만 메인 쿼리의 결과에 포함됩니다. 따라서, `WHERE NOT EXISTS` 절은 실제로 `TRUE` 또는 `FALSE`를 반환하지만, 이 결과에 따라 메인 쿼리가 어떤 레코드를 선택할지 결정합니다.

즉, `WHERE NOT EXISTS`는 다음과 같은 방식으로 동작합니다:

1. **서브쿼리가 결과를 반환하지 않음**:
   - `NOT EXISTS`가 `TRUE`가 됨.
   - 이 경우, 메인 쿼리는 현재 레코드를 결과로 포함합니다.

2. **서브쿼리가 결과를 반환함**:
   - `NOT EXISTS`가 `FALSE`가 됨.
   - 이 경우, 메인 쿼리는 현재 레코드를 결과에 포함하지 않습니다.

### 예제

다음과 같은 예제를 다시 살펴보겠습니다:

```sql
SELECT A.ID
FROM TBL1 A
WHERE NOT EXISTS (SELECT 1 FROM TBL2 B WHERE A.ID = B.ID);
```

여기서:

- **서브쿼리**: `SELECT 1 FROM TBL2 B WHERE A.ID = B.ID`
  - `TBL2`에 `A.ID`와 동일한 `ID` 값이 있는지 확인합니다.

- **NOT EXISTS**:
  - `TBL2`에 동일한 `ID` 값이 없으면 `TRUE`, 있으면 `FALSE`를 반환합니다.

- **메인 쿼리의 결과**:
  - `NOT EXISTS`가 `TRUE`인 경우에만 `A.ID`가 결과에 포함됩니다.

### 요약

- **`WHERE NOT EXISTS`** 절 자체는 `TRUE` 또는 `FALSE` 값을 반환하지만, 메인 쿼리의 결과로는 실제 데이터를 선택합니다.
- 따라서, `WHERE NOT EXISTS`가 `TRUE`가 되는 레코드만 최종 결과로 나타납니다.
- 메인 쿼리의 출력에는 `TRUE`나 `FALSE`가 직접적으로 표시되지 않고, 조건을 만족하는(즉, `TRUE`인) 레코드의 데이터만 포함됩니다.

'SQL 통한 Database 관리' 카테고리의 다른 글

레코드 와 칼럼 차이  (0) 2024.08.20
UNION ALL`과 `NOT EXISTS  (0) 2024.08.20
left outer join  (0) 2024.08.20
cube()  (0) 2024.08.20
start with, connect by prior c, order siblings by  (0) 2024.08.20