To bardzo dobre pytanie, dlatego postanowiłem napisać bardzo szczegółowy artykuł na ten temat na moim blogu.
Model tabeli bazy danych
Załóżmy, że mamy w naszej bazie danych następujące dwie tabele, które tworzą relację jeden do wielu.

studentStół jest rodzicem, astudent_grade to tabela dziecko, ponieważ ma to student_id kolumny klucz obcy odniesienia do identyfikatora kolumny klucza podstawowego w tabeli studentów.
student tableZawiera następujące dwa rekordy:
| id | first_name | last_name | admission_score |
|----|------------|-----------|-----------------|
| 1 | Alice | Smith | 8.95 |
| 2 | Bob | Johnson | 8.75 |
, A student_gradetabela przechowuje klas otrzymali uczniowie:
| 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 |
ISTNIEJE SQL
Powiedzmy, że chcemy, aby wszyscy uczniowie, którzy otrzymali 10 klas z matematyki.
Jeśli interesuje nas tylko identyfikator studenta, możemy uruchomić zapytanie takie jak to:
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
Ale aplikacja jest zainteresowana wyświetlaniem pełnej nazwy, a studentnie tylko identyfikatora, dlatego potrzebujemy informacji zstudent tabeli.
Aby filtrować studentrekordy, które mają 10 stopni z matematyki, możemy użyć operatora EXISTS SQL, takiego jak to:
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
Po uruchomieniu powyższego zapytania widzimy, że wybrany jest tylko wiersz Alice:
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
Zewnętrzne zapytanie wybiera student kolumny wierszy, które chcemy powrócić do klienta. Jednak klauzula WHERE korzysta z operatora EXISTS z powiązanym wewnętrznym podzapytaniem.
Operator EXISTS zwraca wartość true, jeśli podzapytanie zwraca co najmniej jeden rekord, a wartość false, jeśli nie wybrano żadnego wiersza. Aparat bazy danych nie musi całkowicie uruchamiać podkwerendy. Jeśli zostanie dopasowany pojedynczy rekord, operator EXISTS zwróci wartość true i wybrany zostanie powiązany inny wiersz zapytania.
Wewnętrzne podzapytanie jest skorelowane, ponieważ kolumna student_id w student_grade tabeli jest dopasowana do kolumny id zewnętrznej tabeli studenta.
SQL NIE ISTNIEJE
Rozważmy, że chcemy wybrać wszystkich uczniów, którzy nie mają ocen niższych niż 9. W tym celu możemy użyć NOT EXISTS, co neguje logikę operatora EXISTS.
Dlatego operator NOT EXISTS zwraca true, jeśli bazowe podzapytanie nie zwraca rekordu. Jeśli jednak pojedynczy rekord zostanie dopasowany do wewnętrznego podzapytania, operator NOT EXISTS zwróci false, a wykonanie podzapytania można zatrzymać.
Aby dopasować wszystkie rekordy studentów, które nie mają skojarzonego student_grade z wartością mniejszą niż 9, możemy uruchomić następujące zapytanie 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
Po uruchomieniu powyższego zapytania widzimy, że dopasowany jest tylko rekord Alice:
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
Zaletą korzystania z operatorów SQL EXISTS i NOT EXISTS jest to, że wykonywanie wewnętrznego podzapytania można zatrzymać, dopóki znaleziony zostanie pasujący rekord.