이것은 매우 좋은 질문이므로 내 블로그에이 주제에 대한 매우 자세한 기사 를 작성하기로 결정했습니다 .
데이터베이스 테이블 모델
데이터베이스에 일대 다 테이블 관계를 형성하는 다음 두 테이블이 있다고 가정합니다.
student
테이블은 부모이며,student_grade
이 학생 테이블의 ID를 기본 키 열을 참조하는 student_id 외래 키 열이 있기 때문에 자식 테이블입니다.
이에 student table
는 다음 두 가지 레코드가 포함됩니다.
| id | first_name | last_name | admission_score |
|----|------------|-----------|-----------------|
| 1 | Alice | Smith | 8.95 |
| 2 | Bob | Johnson | 8.75 |
그리고 student_grade
테이블에는 학생들이받은 성적이 저장됩니다.
| id | class_name | grade | student_id |
|----|------------|-------|------------|
| 1 | Math | 10 | 1 |
| 2 | Math | 9.5 | 1 |
| 3 | Math | 9.75 | 1 |
| 4 | Science | 9.5 | 1 |
| 5 | Science | 9 | 1 |
| 6 | Science | 9.25 | 1 |
| 7 | Math | 8.5 | 2 |
| 8 | Math | 9.5 | 2 |
| 9 | Math | 9 | 2 |
| 10 | Science | 10 | 2 |
| 11 | Science | 9.4 | 2 |
SQL 존재
수학 수업에서 10 학년을받은 모든 학생들을 원한다고 가정 해 봅시다.
학생 식별자에만 관심이 있다면 다음과 같은 쿼리를 실행할 수 있습니다.
SELECT
student_grade.student_id
FROM
student_grade
WHERE
student_grade.grade = 10 AND
student_grade.class_name = 'Math'
ORDER BY
student_grade.student_id
그러나 응용 프로그램은 student
식별자뿐만 아니라의 전체 이름을 표시하는 데 관심이 있으므로student
테이블의 합니다.
student
Math에서 10 등급을 가진 레코드 를 필터링하기 위해 다음과 같이 EXISTS SQL 연산자를 사용할 수 있습니다.
SELECT
id, first_name, last_name
FROM
student
WHERE EXISTS (
SELECT 1
FROM
student_grade
WHERE
student_grade.student_id = student.id AND
student_grade.grade = 10 AND
student_grade.class_name = 'Math'
)
ORDER BY id
위의 쿼리를 실행할 때 Alice 행만 선택되었음을 알 수 있습니다.
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
외부 쿼리는 student
클라이언트에게 반환하려는 행 열을 선택합니다 . 그러나 WHERE 절은 연관된 내부 서브 쿼리와 함께 EXISTS 연산자를 사용하고 있습니다.
부속 조회가 하나 이상의 레코드를 리턴하면 EXISTS 연산자는 true를 리턴하고 행을 선택하지 않으면 false를 리턴합니다. 데이터베이스 엔진은 하위 쿼리를 완전히 실행할 필요가 없습니다. 단일 레코드가 일치하면 EXISTS 연산자는 true를 리턴하고 연관된 다른 조회 행이 선택됩니다.
내부 하위 쿼리는 student_grade
테이블 이 외부 학생 테이블의 id 열과 일치 됩니다.
존재하지 않는 SQL
9 학년 이하의 모든 학생을 선발한다고 가정 해 봅시다.이를 위해 EXISTS 연산자를 사용하지 않는 NOT EXISTS를 사용할 수 있습니다.
따라서 기본 하위 쿼리가 레코드를 반환하지 않으면 NOT EXISTS 연산자는 true를 반환합니다. 그러나 내부 하위 쿼리와 단일 레코드가 일치하면 NOT EXISTS 연산자는 false를 반환하고 하위 쿼리 실행을 중지 할 수 있습니다.
연관된 student_grade가없는 모든 학생 레코드를 9보다 낮은 값과 일치시키기 위해 다음 SQL 쿼리를 실행할 수 있습니다.
SELECT
id, first_name, last_name
FROM
student
WHERE NOT EXISTS (
SELECT 1
FROM
student_grade
WHERE
student_grade.student_id = student.id AND
student_grade.grade < 9
)
ORDER BY id
위의 쿼리를 실행하면 Alice 레코드 만 일치 함을 알 수 있습니다.
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
따라서 SQL EXISTS 및 NOT EXISTS 연산자를 사용하면 일치하는 레코드가있는 한 내부 서브 쿼리 실행을 중지 할 수 있다는 장점이 있습니다.