Bu çok güzel bir soru, bu yüzden blogumda bu konuyla ilgili çok ayrıntılı bir makale yazmaya karar verdim .
Veritabanı tablosu modeli
Diyelim ki veritabanımızda bire çok tablo ilişkisi oluşturan aşağıdaki iki tablo var.
student
Masa üstüdür ve student_grade
öğrenci tablosundaki id Birincil Anahtar sütununa başvurmak bir student_id Yabancı anahtar sütunu vardır çünkü çocuk tablodur.
student table
Aşağıdaki iki kayıtlarını içerir:
| id | first_name | last_name | admission_score |
|----|------------|-----------|-----------------|
| 1 | Alice | Smith | 8.95 |
| 2 | Bob | Johnson | 8.75 |
Ve student_grade
tablo öğrencilerin aldığı notları saklar:
| 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 VAR
Matematik dersinde 10 not alan tüm öğrencilere sahip olmak istediğimizi varsayalım.
Yalnızca öğrenci tanımlayıcıyla ilgileniyorsak, bunun gibi bir sorgu çalıştırabiliriz:
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
Ancak, uygulama student
yalnızca tanımlayıcıyı değil, a'nın tam adını görüntülemekle de ilgileniyor , bu yüzden student
tablodan da bilgiye ihtiyacımız var .
student
Math'da 10 notu olan kayıtları filtrelemek için EXISTS SQL işlecini şu şekilde kullanabiliriz:
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
Yukarıdaki sorguyu çalıştırırken yalnızca Alice satırının seçildiğini görebiliriz:
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
Dış sorgu student
istemciye dönmekle ilgilendiğimiz satır sütunlarını seçer . Ancak, WHERE yan tümcesi, EXISTS işlecini ilişkili bir iç alt sorguyla birlikte kullanıyor.
EXISTS işleci, alt sorgu en az bir kayıt döndürürse true, seçili satır yoksa false değerini döndürür. Veritabanı altyapısının alt sorguyu tamamen çalıştırması gerekmez. Tek bir kayıt eşleşirse, EXISTS operatörü true değerini döndürür ve ilişkili diğer sorgu satırı seçilir.
student_grade
Tablonun student_id sütunu , dış öğrenci tablosunun id sütunuyla eşleştirildiği için iç alt sorgu ilişkilendirilir .
SQL VAR DEĞİL
Notu 9'dan düşük olmayan tüm öğrencileri seçmek istediğimizi düşünelim. Bunun için EXISTS operatörünün mantığını reddeden NOT EXISTS'i kullanabiliriz.
Bu nedenle, altta yatan alt sorgu kayıt döndürmezse NOT EXISTS işleci true değerini döndürür. Ancak, iç alt sorgu tarafından tek bir kayıt eşleştirilirse, NOT EXISTS operatörü false değerini döndürür ve alt sorgu yürütmesi durdurulabilir.
İlişkili student_grade olmayan tüm öğrenci kayıtlarını 9'dan düşük bir değerle eşleştirmek için aşağıdaki SQL sorgusunu çalıştırabiliriz:
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
Yukarıdaki sorguyu çalıştırırken yalnızca Alice kaydının eşleştiğini görebiliriz:
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
Bu nedenle, SQL EXISTS ve NOT EXISTS işleçlerini kullanmanın avantajı, eşleşen bir kayıt bulunduğu sürece iç alt sorgu yürütmenin durdurulabilmesidir.