これは非常に良い質問なので、このトピックについて非常に詳細な記事をブログに書くことにしました。
データベーステーブルモデル
データベースに次の2つのテーブルがあり、1対多のテーブルリレーションシップを形成するとします。
student
テーブルには、親である、そしてstudent_grade
それは学生のテーブルのid主キー列を参照STUDENT_ID外部キー列を持っているので、子テーブルです。
にstudent table
は、次の2つのレコードが含まれています。
| 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年生を取得したすべての学生を取得したいとします。
学生IDのみに関心がある場合は、次のようなクエリを実行できます。
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演算子は、サブクエリが少なくとも1つのレコードを返す場合はtrueを返し、行が選択されていない場合はfalseを返します。データベースエンジンは、サブクエリを完全に実行する必要はありません。単一のレコードが一致した場合、EXISTS演算子はtrueを返し、関連する他のクエリ行が選択されます。
student_grade
テーブルのstudent_id列が外部のStudentテーブルの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演算子を使用する利点は、一致するレコードが見つかる限り、内部のサブクエリの実行を停止できることです。