Lekcje modułu (4/4)
Zapytanie wewnątrz innego: podzapytania
Nauczyłeś się, jak wyodrębniać, filtrować, grupować, łączyć i przekształcać. Tam to ostatnia podstawowa idea: umieszczenie zapytania w innym. To są zwane podzapytaniami i są krokiem, który pozwala odpowiedzieć na pytania np. „kto zarabia powyżej średniej?” lub „w których działach ktoś taki pracuje przypisany do projektu?”.
Podstawowa składnia
Podzapytanie to SELECT owinięte w nawiasy, używane zamiast pojedynczego
wartość lub lista wartości w innym zapytaniu:
-- Find who earns MORE THAN THE COMPANY AVERAGE:
SELECT first_name, last_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);Silnik najpierw uruchamia podzapytanie — SELECT AVG(salary) FROM employees
zwraca pojedynczą liczbę — i następnie używa tej liczby w zewnętrznym WHERE
tak jakbyś pisał to ręcznie. To jest właśnie zaleta: tak
nie musisz znać średniej z góry, SQL oblicza ją za Ciebie.
Trzy najpopularniejsze „typy”
1. Podzapytanie zwracające pojedynczą wartość
Powyższy przykład: podzapytanie generuje jeden wiersz, jedną kolumnę (tzw
skalar). Używasz go z =, >, < i tak dalej.
-- Employee with the highest salary:
SELECT first_name, last_name
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);2. Podzapytanie zwracające listę
Podzapytanie generuje jedna kolumna, wiele wierszy. Używasz go z KODPH0:
-- Departments that have at least one employee:
SELECT name
FROM departments
WHERE id IN (SELECT DISTINCT department_id
FROM employees
WHERE department_id IS NOT NULL);3. Podzapytanie jako „tabela” (FROM)
Podzapytanie może również zastąpić tabelę w FROM. Przydaje się
wstępnie obliczyć agregaty, a następnie je przefiltrować lub połączyć:
-- Departments with average salary above 40000:
SELECT d.name, medie.stipendio_medio
FROM departments AS d
JOIN (SELECT department_id, AVG(salary) AS stipendio_medio
FROM employees
GROUP BY department_id) AS medie
ON d.id = medie.department_id
WHERE medie.stipendio_medio > 40000;Podzapytanie czy DOŁĄCZ? Kiedy użyć którego
Często ten sam wynik można uzyskać za pomocą JOIN lub podzapytania.
Praktyczna zasada:
- Aby filtrować wiersze jednej tabeli na podstawie właściwości innej
("pracownicy, których działy są..."),
IN (subquery)jest bardzo czytelny. - Aby połączyć w wyniku kolumny z wielu tabel, użyj
JOIN. - Aby obliczyć agregat i użyć go jako progu (”powyżej średnia"), podzapytanie skalarne jest naturalnym wyborem.
W praktyce zobaczysz jedno i drugie: silnik SQL często optymalizuje je w ten sam sposób sposób. Wybierz formularz, który najlepiej się czyta.
Spróbuj
Znajdź imię (imię), nazwisko (nazwisko) i wynagrodzenie (wynagrodzenie) pracowników, którzy zarabiają ŚCIŚLE więcej niż średnia w firmie. Trzy kolumny.
Pokaż wskazówkę
Zastępować ? z podzapytaniem SELECT AVG(wynagrodzenie) FROM pracowników — zwraca pojedynczą liczbę, która będzie stanowić próg.
Rozwiązanie dostępne po 3 próbach
Przejrzyj ćwiczenie
Podaj nazwę (departments.name) działów, które mają co najmniej jednego pracownika z pensją znacznie większą niż 50000. Użyj podzapytania z IN. Uporządkuj alfabetycznie.
Pokaż wskazówkę
Podzapytanie wewnętrzne zwraca identyfikatory działów, które zatrudniają pracowników z wynagrodzeniem > 50000. Następnie w zapytaniu zewnętrznym WHERE id IN (...).
Rozwiązanie dostępne po 3 próbach