Przejdź do głównej treści
eLearner.app
Moduł 4 · Lekcja 4 z 416/57 w kursie~12 min
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:

SQL
-- 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.

SQL
-- 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:

SQL
-- 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ć:

SQL
-- 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

Ćwiczenie#sql.m4.l4.e1
Próby: 0Ładowanie...

Znajdź imię (imię), nazwisko (nazwisko) i wynagrodzenie (wynagrodzenie) pracowników, którzy zarabiają ŚCIŚLE więcej niż średnia w firmie. Trzy kolumny.

Ładowanie edytora...
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

Ćwiczenie#sql.m4.l4.e2
Próby: 0Ładowanie...

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.

Ładowanie edytora...
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