Lekcja 24: Podzapytania (Subqueries)

Preview Mode

You're viewing this material in preview mode. Sign up to track your progress and access all features.

Lekcja 24: Podzapytania (Subqueries)
Required In Progress

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:

  1. (Krok 1 - Podzapytanie) Znajdź ID_Klasy dla wszystkich klas 'Mat-Fiz'.
  2. (Krok 2 - Zapytanie zewnętrzne) Znajdź uczniów, których ID_Klasy jest 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:

  1. (Krok 1 - Podzapytanie) Oblicz liczbę uczniów w każdej klasie (GROUP BY ID_Klasy).
  2. (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.