CodeGym /Kursy /SQL SELF /Użycie podzapytań w FROM

Użycie podzapytań w FROM

SQL SELF
Poziom 14, Lekcja 1
Dostępny

Wskakujemy jeszcze głębiej do króliczej nory: zobaczmy, jak używać podzapytań w konstrukcji FROM. To jeden z najczęstszych trików SQL-developerów, bo pozwala tworzyć potężne tymczasowe tabele dokładnie "na miejscu" i używać ich tak, jakby istniały w bazie danych.

Wyobraź sobie, że robisz raport, który wymaga obliczeń, grupowania albo filtrowania danych, ale nie chcesz tworzyć dodatkowych tymczasowych tabel na serwerze. Co wtedy? Tu właśnie ratują nas podzapytania w FROM. Pozwalają one na:

  • Tymczasowe łączenie danych albo ich agregowanie przed głównym zapytaniem.
  • Tworzenie uporządkowanych zestawów danych "w locie".
  • Zmniejszenie liczby operacji, wymagając od bazy minimalnego przechowywania danych pośrednich.

Podzapytania w FROM działają jak mini-tabele, które możesz wykorzystać w głównym zapytaniu. To trochę jak budowanie z klocków: szybko, elastycznie i bez zbędnych kosztów :)

Podstawy podzapytań w FROM

W podzapytaniach w FROM używamy podzapytań, żeby stworzyć tymczasową tabelę (albo podtabelę), która staje się częścią całego zapytania. Trzeba zrobić trzy kluczowe kroki:

  1. Napisać podzapytanie w konstrukcji FROM w nawiasach okrągłych.
  2. Przypisać alias (pseudonim) dla podzapytania.
  3. Używać tego aliasu tak, jakby to była normalna tabela.

Składnia

SELECT kolumny
FROM (
    SELECT kolumny
    FROM tabela
    WHERE warunek
) AS pseudonim
WHERE zewnętrzny_warunek;

Brzmi groźnie? To lecimy z przykładami.

Przykład: Studenci i średnia ocena

Załóżmy, że mamy dwie tabele:

students (dane o studentach — ich imię i ID):

student_id student_name
1 Alex
2 Anna
3 Dan

grades (dane o ocenach studentów):

grade_id student_id grade
1 1 80
2 1 85
3 2 90
4 3 70
5 3 75

Teraz zadanie: uzyskać listę studentów i ich średnią ocenę.

Możemy zacząć od prostego podzapytania, które liczy średnią ocenę każdego studenta, a potem użyć tego w głównym zapytaniu.

SELECT s.student_name, g.avg_grade
FROM (
    SELECT student_id, AVG(grade) AS avg_grade
    FROM grades
    GROUP BY student_id
) AS g
JOIN students AS s ON s.student_id = g.student_id;

Wynik:

student_name avg_grade
Alex 82.5
Anna 90.0
Dan 72.5

Tymczasowe tabele "w locie"

Podzapytania w FROM są szczególnie przydatne, gdy musisz zrobić więcej niż jeden poziom przetwarzania danych. Na przykład, jeśli chcesz nie tylko uzyskać średnią ocenę, ale też policzyć maksymalną ocenę dla każdego studenta — wszystko w jednym zapytaniu.

SELECT g.student_id, g.avg_grade, g.max_grade
FROM (
    SELECT student_id, 
           AVG(grade) AS avg_grade, 
           MAX(grade) AS max_grade
    FROM grades
    GROUP BY student_id
) AS g;

Wynik:

student_id avg_grade max_grade
1 82.5 85
2 90 90
3 72.5 75

Zwróć uwagę, że to działa jak pełnoprawna tymczasowa tabela ze swoimi kolumnami: avg_grade i max_grade.

Kiedy najlepiej używać podzapytań w FROM?

Dla danych zagregowanych. Jeśli chcesz najpierw zrobić obliczenia (np. policzyć średnią, sumy albo maksimum), a potem połączyć wyniki z innymi tabelami.

Do filtrowania danych. Gdy trzeba przefiltrować dane przed połączeniem z główną tabelą.

Do uproszczenia złożonych zapytań. Podzielenie trudnych zadań na etapy pomaga uniknąć chaosu.

Przykład: Raport o studentach z dwoma poziomami przetwarzania

Wyobraź sobie, że chcesz znaleźć studentów, którzy mają średnią ocenę powyżej 80. Zaczynamy od podzapytania, które liczy średnie oceny, a potem używamy go w filtrze.

SELECT s.student_name, g.avg_grade
FROM students AS s
JOIN (
    SELECT student_id, AVG(grade) AS avg_grade
    FROM grades
    GROUP BY student_id
) AS g ON s.student_id = g.student_id
WHERE g.avg_grade > 80;

Wynik:

student_name avg_grade
Alex 82.5
Anna 90.0

Wskazówki i rekomendacje

Obowiązkowy alias. Zawsze nadaj alias podzapytaniu (np. AS g), bo inaczej PostgreSQL nie będzie wiedział, jak się odwołać do tej "tymczasowej tabeli".

Optymalizacja. Podzapytania w FROM mogą być wolniejsze niż zwykłe łączenia tabel (JOIN), szczególnie jeśli filtrujesz dane wewnątrz podzapytania.

Indeksowanie. Upewnij się, że pola używane do łączenia, indeksy i filtry są zoptymalizowane — to mocno wpływa na wydajność.

Przykład trudniejszego zapytania: kursy i liczba studentów

To teraz coś bardziej praktycznego. Wyobraź sobie, że mamy taką tabelę:

courses (lista kursów):

course_id course_name
1 SQL Basics
2 Python Basics

I enrollments (zapisy studentów na kursy):

student_id course_id
1 1
1 2
2 1

Teraz chcemy się dowiedzieć, ilu studentów jest zapisanych na każdy kurs.

SELECT c.course_name, e.students_count
FROM courses AS c
JOIN (
    SELECT course_id, COUNT(student_id) AS students_count
    FROM enrollments
    GROUP BY course_id
) AS e ON c.course_id = e.course_id;

Wynik:

course_name students_count
SQL Basics 2
Python Basics 1

Mam nadzieję, że wykład Ci się spodobał... ale następny będzie jeszcze ciekawszy :)

2
Zadanie
SQL SELF, poziom 14, lekcja 1
Niedostępne
Zliczanie liczby ocen studentów
Zliczanie liczby ocen studentów
2
Zadanie
SQL SELF, poziom 14, lekcja 1
Niedostępne
Liczba studentów na każdym kursie
Liczba studentów na każdym kursie
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION