[SQL] Może mi ktoś wytłumaczyć na tym przykładzie jak działają podzapytania?

0

Cześć, tak jak w temacie. Wklepuję to w google i jakieś misz-masz, nie rozumiem co tam ludzie piszą bo mają jakieś dziwne przykłady. Mam swój z zajęć, może mi ktoś na jego podstawie napisać dlaczego jest ono tak skonstruowane? Będę wdzięczny.

SELECT imie, nazwisko FROM student WHERE student.id IN (SELECT ocena.id_student FROM ocena WHERE ocena.wartosc > 4);

Oraz takie:

SELECT * FROM student as s WHERE NOT EXISTS (SELECT * FROM ocena as o WHERE o.id_student = s.id);

Słowa kluczowe znam.

5

Wykonaj samo podzapytanie.

SELECT ocena.id_student FROM ocena WHERE ocena.wartosc > 4

Z wyniku weź liczby i wpisz w nawias zamiast podzapytania. Na przykład:

SELECT imie, nazwisko FROM student WHERE student.id IN (1, 2, 3, 4);

Efekt otrzymasz identyczny z tą różnicą, ze wykonałeś podzapytanie sam, a normalnie wykonuje je silnik bazy danych.

3

Uzupełnię to co napisał @Sarrus bo technicznie wszystko się zgadza, ale zacznij od odpowiedzi co dane zapytanie wyciąga.

Pierwsze pokazuje studentów którzy otrzymali ocene wiekszą od 4. Czyli musisz wyciągnąć id studentów:

SELECT ocena.id_student FROM ocena WHERE ocena.wartosc > 4

i na podstawie zwróconych id wygenerować zapytanie

SELECT imie, nazwisko FROM student WHERE student.id IN (1, 2, 3, 4);

Oczywiście nie ma to sensu, bo można w WHERE zapytać o tą konkretną grupę, dlatego wykorzystujemy podzapytanie.

Drugie przedstawione przez ciebie zapytanie wyciaga studentów bez ocen. Tu jest troche inaczej bo to podzapytanie jest skorelowane z zapytaniem nadrzędnym, konkretnie ten warunek:

o.id_student = s.id

o to tabela oceny wykorzystana w podzapytaniu, s to tabela studenci wykorzystana w zapytaniu nadrzędnym, czyli warunek jest sprawdzany dla każdego id występującego w tabeli student.

0

Czy w takim razie podzapytanie jest w jakiś stopniu zamiennikiem, bądź lepszą/gorszą wersją złączenia? Bo to samo chyba mogę zrobić za pomocą INNER JOIN, czy się mylę?

Chciałbym jeszcze poruszyć to zapytanie skorelowane:

SELECT imie, nazwisko, (SELECT COUNT(*) from ocena WHERE ocena.id_student = student.id AND ocena.wartosc > 4) as ile_ocen FROM student  LIMIT 40;

Wybieram imię, nazwisko. Wybieram ilość ocen, gdzie id_student z tabeli oceny jest połączone z id tabeli student, następnie WARTOŚĆ z tabeli oceny jest większa od 4. To zapytanie jest nazwane jako ile_ocen - dlaczego FROM student trzeba dodać, skoro już podaliśmy wcześniej tyle tabel? Limit 40, to pokaże 40 osób.

2

Czy w takim razie podzapytanie jest w jakiś stopniu zamiennikiem, bądź lepszą/gorszą wersją złączenia?

To nie lepsze/gorsze, jak w każdym języku jedną rzecz można zrobić na kilka sposobów.

Bo to samo chyba mogę zrobić za pomocą INNER JOIN, czy się mylę?

Mylisz się, możesz użyć ale left join:


select
     student.*
from 
    student s
    left join oceny o on o.id_student = s.id
where
 o.id is null

Możesz też użyć negacji z in

SELECT imie, nazwisko FROM student WHERE not student.id IN (SELECT ocena.id_student FROM ocena);

dlaczego FROM student trzeba dodać, skoro już podaliśmy wcześniej tyle tabel?

Podzapytanie jak nazwa wskazuje mieści się w zapytaniu (nadrzędnym), więc to zapytanie nadrzędne musi mieć prawidlową skladnię.
Pomiń podzapytanie:

SELECT imie, nazwisko FROM student

I odpowiedz: Czy zadziała bez student?

1 użytkowników online, w tym zalogowanych: 0, gości: 1