Zapytanie wewnątrz zapytania
Podzapytanie (subquery) to kompletne zapytanie SELECT, które jest zagnieżdżone wewnątrz innego, nadrzędnego zapytania (tzw. zapytania zewnętrznego). Są one potężnym narzędziem do wykonywania wieloetapowych operacji logicznych w ramach jednego polecenia.
Podzapytania w klauzuli WHERE (np. z IN lub operatorami porównania)
To jest najczęstsze i najbardziej intuicyjne zastosowanie podzapytań. Podzapytanie zwraca listę wartości (lub pojedynczą wartość), która jest następnie używana przez warunek WHERE zapytania zewnętrznego.
Przykład
Znajdź wszystkich uczniów, którzy należą do klas o profilu 'Mat-Fiz'.
Problem: Uczniowie nie mają informacji o profilu, tylko ID_Klasy. Klasy mają profil.
Logika:
- (Krok 1 - Podzapytanie) Znajdź
ID_Klasydla wszystkich klas 'Mat-Fiz'. - (Krok 2 - Zapytanie zewnętrzne) Znajdź uczniów, których
ID_Klasyjest na liście z Kroku 1.
Połączenie (Subquery):
SELECT Imie, Nazwisko
FROM Uczniowie
WHERE ID_Klasy IN (
-- Początek podzapytania
SELECT ID_Klasy
FROM Klasy
WHERE Profil = 'Mat-Fiz'
-- Koniec podzapytania
);
Podzapytania w klauzuli FROM (tabela pochodna)
Podzapytanie może być również umieszczone w klauzuli FROM. W takim przypadku tworzy ono tabelę pochodną (derived table) – czyli tymczasowy, wirtualny zestaw wyników, który zapytanie zewnętrzne traktuje jak zwykłą, fizyczną tabelę.
Ważna reguła: Podzapytanie w klauzuli FROM musi mieć nadany alias (za pomocą AS).
Przykład
Oblicz średnią liczbę uczniów w klasie.
Logika:
- (Krok 1 - Podzapytanie) Oblicz liczbę uczniów w każdej klasie (
GROUP BY ID_Klasy). - (Krok 2 - Zapytanie zewnętrzne) Oblicz średnią z wyników Kroku 1.
Połączenie (Subquery):
-- To jest zapytanie zewnętrzne (Krok 2)
SELECT AVG(LiczbaUczniow) AS SredniaLiczbaUczniowWKlasie
FROM (
-- Początek podzapytania (tabeli pochodnej) (Krok 1)
SELECT COUNT(*) AS LiczbaUczniow
FROM Uczniowie
GROUP BY ID_Klasy
-- Koniec podzapytania
) AS StatystykiKlas; -- Alias jest obowiązkowy!
Podzapytania skorelowane (wprowadzenie do koncepcji)
To jest zaawansowany typ podzapytania.
Standardowe podzapytanie (jak to w IN) jest niezależne i uruchamia się tylko jeden raz. Podzapytanie skorelowane (correlated subquery) to takie, które w swojej treści (np. w swoim WHERE) odwołuje się do kolumn z zapytania zewnętrznego.
W efekcie, podzapytanie skorelowane jest uruchamiane wielokrotnie – raz dla każdego pojedynczego wiersza przetwarzanego przez zapytanie zewnętrzne. Są one wolniejsze, ale bardzo potężne.
Przykład
Znajdź uczniów, których średnia jest wyższa niż średnia w ich własnej klasie.
SELECT U1.Imie, U1.Nazwisko, U1.Srednia
FROM Uczniowie AS U1
WHERE U1.Srednia > (
-- Początek podzapytania skorelowanego
SELECT AVG(U2.Srednia)
FROM Uczniowie AS U2
WHERE U2.ID_Klasy = U1.ID_Klasy -- KORELACJA! Odwołanie do U1.
-- Koniec podzapytania
);
Dla każdego ucznia U1, wewnętrzne zapytanie uruchomi się ponownie, aby obliczyć średnią tylko dla jego klasy.