CodeGym /Kursy /SQL SELF /Wiele JOIN w jednym zapytaniu

Wiele JOIN w jednym zapytaniu

SQL SELF
Poziom 12, Lekcja 1
Dostępny

Wyobraź sobie, że każda tabela w twojej bazie to kawałek jednej wielkiej układanki. Tabela studentów wie, kto się uczy, tabela kursów — czego uczą, a tabela zapisów — kto na co jest zapisany. Ale osobno te kawałki nie mówią zbyt wiele. Chcesz zobaczyć cały obrazek? Trzeba je połączyć — i tu na scenę wchodzi wielokrotny JOIN.

W realnym życiu dane są często zorganizowane w powiązane tabele, żeby zachować strukturę i nie powielać informacji. Na przykład, w naszej bazie uniwersytetu mamy takie tabele:

  • students — dane o studentach.
  • enrollments — info o zapisach studentów na kursy.
  • courses — info o kursach.

Jeśli chcemy dostać pełną listę studentów, ich kursów i nauczycieli, trzeba połączyć trzy tabele używając JOIN.

Kolejność wykonywania JOIN

Przy użyciu kilku JOIN, PostgreSQL przetwarza je od lewej do prawej. To znaczy, że najpierw łączone są dwie pierwsze tabele, potem wynik jest łączony z trzecią tabelą i tak dalej.

Przykład:

SELECT *
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id;
  1. Najpierw łączone są tabele students i enrollments po kolumnie students.id = enrollments.student_id.
  2. Wynik pierwszego połączenia jest używany do połączenia z tabelą courses po kolumnie enrollments.course_id = courses.id.

Kolejność wykonywania jest szczególnie ważna, gdy w zapytaniu biorą udział duże tabele. Zła struktura JOIN może mocno spowolnić działanie zapytania.

Przykład: Lista studentów, ich kursów i nauczycieli

Załóżmy, że mamy takie tabele z danymi:

Tabela students:

id name
1 Otto Song
2 Maria Chi
3 Alex Lin

Tabela courses:

id name teacher
101 Mathematics Ellen Moore
102 Physics James Okoro
103 Computer Science Nina Delgado

Tabela enrollments:

student_id course_id
1 101
1 103
2 102
3 101

Zapytanie:

SELECT
    students.name AS student_name,
    courses.name AS course_name,
    courses.teacher AS teacher_name
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id;

Wynik:

student_name course_name teacher_name
Otto Song Mathematics Ellen Moore
Otto Song Computer Science Nina Delgado
Maria Chi Physics James Okoro
Alex Lin Mathematics Ellen Moore

Filtrowanie w zapytaniach z wieloma JOIN

Możesz stosować warunki filtrowania do zapytań z JOIN, żeby ograniczyć ilość zwracanych danych i przyspieszyć wykonanie zapytania. Na przykład, jeśli chcesz wyświetlić tylko tych studentów, którzy uczą się na kursie "Mathematics":

SELECT
    students.name AS student_name,
    courses.name AS course_name
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id
WHERE courses.name = 'Mathematics';

Wynik:

student_name course_name
Otto Song Mathematics
Alex Lin Mathematics

Optymalizacja zapytań z wieloma JOIN

Przy pracy z dużymi tabelami optymalizacja zapytań robi się mega ważna. Oto kilka tipów:

  1. Używaj indeksów

Indeksy pozwalają PostgreSQL działać szybciej, szczególnie przy łączeniu po kluczowych polach. Upewnij się, że na kolumnach student_id i course_id w tabeli enrollments są indeksy.

Przykład tworzenia indeksu:

CREATE INDEX idx_enrollments_student_id ON enrollments(student_id);
CREATE INDEX idx_enrollments_course_id ON enrollments(course_id);

Więcej o indeksach dowiesz się na kolejnych poziomach, ale już teraz warto o nich wspomnieć. Są bardzo często powiązane z JOIN.

  1. Filtruj dane na wczesnym etapie

Stosuj warunki WHERE, żeby zmniejszyć ilość przetwarzanych wierszy zanim wykonasz JOIN. Na przykład:

SELECT
    students.name AS student_name,
    courses.name AS course_name
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id
WHERE 
    courses.teacher = 'Ivan Pietrow';
  1. Minimalizuj ilość wierszy do połączenia

Zamiast łączyć wszystkie rekordy z dwóch tabel, spróbuj najpierw je przefiltrować podzapytaniami:

SELECT
    students.name AS student_name,
    courses.name AS course_name
FROM 
    (SELECT * FROM students WHERE id IN (1, 2)) sub_students
INNER JOIN enrollments ON sub_students.id = enrollments.student_id
INNER JOIN courses ON enrollments.course_id = courses.id;

Więcej o zagnieżdżonych SELECT-ach dowiesz się już na następnym poziomie :P

Przykład trudniejszego połączenia: studenci, kursy i wydziały

Załóżmy, że dodajemy jeszcze jedną tabelę faculties:

Tabela faculties:

id name
10 Engineering
20 Natural Sciences

Tabela courses zaktualizowana:

id name teacher faculty_id
101 Mathematics Ellen Moore 10
102 Physics James Okoro 20
103 Computer Science Nina Delgado 10

Żeby dostać listę studentów, kursów i wydziałów, dodajemy jeszcze jeden JOIN:

SELECT
    students.name AS student_name,
    courses.name AS course_name,
    faculties.name AS faculty_name
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id
    INNER JOIN faculties ON courses.faculty_id = faculties.id;

Wynik:

student_name course_name faculty_name
Otto Song Mathematics Engineering
Otto Song Computer Science Engineering
Maria Chi Physics Natural Sciences
Alex Lin Mathematics Engineering

SQL-zapytania z wieloma JOIN mogą być skomplikowane, ale pozwalają tworzyć mocne raporty i wyciągać wartościowe info. Jeśli dobrze je zoptymalizujesz i poukładasz, staną się twoim narzędziem do pracy z dużymi bazami danych.

2
Zadanie
SQL SELF, poziom 12, lekcja 1
Niedostępne
Podstawowe zapytanie z wieloma JOIN
Podstawowe zapytanie z wieloma JOIN
2
Zadanie
SQL SELF, poziom 12, lekcja 1
Niedostępne
Filtrowanie danych z użyciem WHERE i wielu JOIN
Filtrowanie danych z użyciem WHERE i wielu JOIN
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION