Zagnieżdżone Podzapytania (Subqueries)
Jak zbudować incepcję w SQL - zapytanie w zapytaniu. Dowiedz się jak wyciągnąć np. osoby zarabiające więcej niż średnia.
Podzapytania w SQL (Subqueries)
Czasami żeby znaleźć odpowiedź na jedno pytanie, musisz najpierw zadać bazie drugie pytanie.
Wyobraź sobie zadanie: "Wyświetl imiona i nazwiska pracowników, którzy zarabiają więcej niż wynosi średnia pensja w firmie".
Nie możesz napisać wprost:
SELECT Imie, Nazwisko FROM Pracownicy WHERE Pensja > AVG(Pensja); -- TO JEST BŁĄD!Baza zrzuci błąd, ponieważ funkcje agregujące (jak AVG) nie mogą być "ot tak" wsadzane do instrukcji WHERE.
Rozwiązaniem jest zastosowanie podzapytania (zapytania zagnieżdżonego), które najpierw wyliczy średnią z tyłu sceny, a potem podstawi ją do zapytania właściwego.
1. Podzapytanie w WHERE
Budujemy główne zapytanie i tam gdzie potrzebujemy naszej policzonej wartości, otwieramy nawias okrągły () i wsadzamy całkiem nowego SELECTa.
SELECT Imie, Nazwisko, Pensja
FROM Pracownicy
WHERE Pensja > (
SELECT AVG(Pensja)
FROM Pracownicy
);Zauważ: Baza najpierw wykonuje podzapytanie wewnątrz nawiasu (dostaje z niego wynik np. 3200), a potem podstawia to pod główny warunek: WHERE Pensja > 3200.
Interaktywna Konsola: Podzapytanie w klauzuli WHERE
Wyszukaj pracowników, których zarobki są wyższe od średniej w całej firmie.
2. Podzapytanie ze zbiorem wyników (IN)
Jeśli podzapytanie wewnątrz nawiasu nie zwróci jednej konkretnej liczby (jak średnia pensja), ale zwróci całą listę/kolumnę liczb, nie możemy uzyć znaku równości = ani >, bo to nie ma sensu (czy pensja > [zbiór liczb]?).
W takim przypadku, jeśli szukamy czy dana wartość znajduje się w zwróconym zbiorze, używamy operatora IN.
Zadanie: Znajdź klientów, którzy zrobili zakupy w 2023 roku, nie używając JOIN.
SELECT Imie, Nazwisko
FROM Klienci
WHERE ID_Klienta IN (
SELECT ID_Klienta
FROM Zamowienia
WHERE YEAR(DataZamowienia) = 2023
);[!WARNING] Kiedy NIE używać podzapytań? Jeśli używasz
INz ciężkim podzapytaniem przy 100 tysiącach rekordów, baza potrafi "zmulic", ponieważ w skrajnych przypadkach potrafi ewaluować to podzapytanie dla każdego wiersza od nowa (choć nowsze silniki to optymalizują). W 90% przypadków operator JOIN jest szybszy i bezpieczniejszy od zagnieżdżonych podzapytań typuIN. Na maturze z informatyki i egzaminie INF.03 zbiory są jednak małe i nie ma to aż takiego znaczenia czasowego, więc rób to tak, jak Ci wygodniej!
