Ini adalah pertanyaan yang sangat bagus, jadi saya memutuskan untuk menulis artikel yang sangat rinci tentang topik ini di blog saya.
Model tabel basis data
Mari kita asumsikan kita memiliki dua tabel berikut dalam database kita, yang membentuk hubungan tabel satu-ke-banyak.
The student
tabel orangtua, dan student_grade
adalah tabel anak karena memiliki kolom student_id Key Foreign referensi id Primary Key kolom dalam tabel mahasiswa.
Ini student table
berisi dua catatan berikut:
| id | first_name | last_name | admission_score |
|----|------------|-----------|-----------------|
| 1 | Alice | Smith | 8.95 |
| 2 | Bob | Johnson | 8.75 |
Dan, student_grade
meja menyimpan nilai yang diterima siswa:
| 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 ADA
Katakanlah kita ingin mendapatkan semua siswa yang telah menerima nilai 10 di kelas Matematika.
Jika kami hanya tertarik pada pengidentifikasi siswa, maka kami dapat menjalankan kueri seperti ini:
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
Tapi, aplikasi ini tertarik untuk menampilkan nama lengkap a student
, bukan hanya pengenal, jadi kita perlu info dari student
tabel juga.
Untuk memfilter student
catatan yang memiliki nilai 10 dalam Matematika, kita dapat menggunakan operator SQL EXIS, seperti ini:
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
Saat menjalankan kueri di atas, kita dapat melihat bahwa hanya baris Alice yang dipilih:
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
Kueri luar memilih student
kolom baris yang ingin kami kembalikan ke klien. Namun, klausa WHERE menggunakan operator EXISTS dengan subquery dalam yang terkait.
Operator EXISTS mengembalikan true jika subquery mengembalikan setidaknya satu record dan false jika tidak ada baris yang dipilih. Mesin basis data tidak harus menjalankan subquery sepenuhnya. Jika satu catatan cocok, operator EXISTS mengembalikan true, dan baris kueri lainnya yang terkait dipilih.
Subquery dalam dikorelasikan karena kolom student_id dari student_grade
tabel dicocokkan dengan kolom id dari tabel siswa luar.
SQL TIDAK ADA
Mari kita pertimbangkan bahwa kita ingin memilih semua siswa yang tidak memiliki nilai lebih rendah dari 9. Untuk ini, kita dapat menggunakan TIDAK ADA, yang meniadakan logika operator EXISTS.
Oleh karena itu, operator NOT EXISTS mengembalikan true jika subquery yang mendasarinya tidak mengembalikan catatan. Namun, jika catatan tunggal dicocokkan dengan subquery batin, operator BUKAN ada akan kembali palsu, dan eksekusi subquery dapat dihentikan.
Untuk mencocokkan semua catatan siswa yang tidak memiliki tingkat student_grade terkait dengan nilai lebih rendah dari 9, kita dapat menjalankan kueri SQL berikut:
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
Saat menjalankan kueri di atas, kita dapat melihat bahwa hanya catatan Alice yang cocok:
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
Jadi, keuntungan menggunakan operator SQL EXIS dan NOT EXISTS adalah bahwa eksekusi subquery bagian dalam dapat dihentikan selama ditemukan catatan yang cocok.