Təsəvvür elə ki, bazandakı hər cədvəl böyük bir puzzle-ın hissəsidir. Kim oxuyur - bunu students cədvəli bilir, nə öyrədilir - bunu courses cədvəli, kim hansı kursa yazılıb - bunu da enrollments cədvəli. Amma bunlar ayrı-ayrılıqda heç nə demir. Bütün şəkli görmək istəyirsən? Onları birləşdirmək lazımdır - və burada səhnəyə çoxlu JOIN çıxır.
Real həyatda datalar çox vaxt əlaqəli cədvəllərdə saxlanılır ki, struktur olsun və artıq məlumat olmasın. Məsələn, bizim universitet bazasında belə cədvəllər var:
students— tələbələr haqqında məlumat.enrollments— tələbələrin kurslara yazılması haqqında info.courses— kurslar haqqında info.
Əgər tələbələrin, onların kurslarının və müəllimlərinin tam siyahısını almaq istəyirik, üç cədvəli JOIN ilə birləşdirməliyik.
JOIN əməliyyatlarının icra ardıcıllığı
Bir neçə JOIN istifadə edəndə, PostgreSQL onları soldan sağa icra edir. Yəni əvvəlcə ilk iki cədvəl birləşdirilir, sonra nəticə üçüncü cədvəllə birləşdirilir və s.
Nümunə:
SELECT *
FROM students
INNER JOIN enrollments ON students.id = enrollments.student_id
INNER JOIN courses ON enrollments.course_id = courses.id;
- Əvvəlcə
studentsvəenrollmentscədvəlləristudents.id = enrollments.student_idsütunu ilə birləşdirilir. - Birinci birləşmənin nəticəsi
enrollments.course_id = courses.idsütunu iləcoursescədvəli ilə birləşdirilir.
Ardıcıllıq xüsusilə böyük cədvəllərlə işləyəndə vacibdir. JOIN strukturunu səhv qurmaq performansın ciddi düşməsinə səbəb ola bilər.
Nümunə: Tələbələr, onların kursları və müəllimləri siyahısı
Tutaq ki, belə cədvəllərimiz var:
students cədvəli:
| id | name |
|---|---|
| 1 | Otto Song |
| 2 | Maria Chi |
| 3 | Alex Lin |
courses cədvəli:
| id | name | teacher |
|---|---|---|
| 101 | Mathematics | Ellen Moore |
| 102 | Physics | James Okoro |
| 103 | Computer Science | Nina Delgado |
enrollments cədvəli:
| student_id | course_id |
|---|---|
| 1 | 101 |
| 1 | 103 |
| 2 | 102 |
| 3 | 101 |
Sorğu:
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;
Nəticə:
| 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 |
Çoxlu JOIN ilə sorğularda filtrasiya
JOIN ilə sorğularda filtrasiya şərtləri tətbiq edə bilərsən ki, qaytarılan datanın miqdarını azaldıb sorğunu sürətləndirəsən. Məsələn, yalnız "Mathematics" kursunda oxuyan tələbələri çıxarmaq üçün:
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';
Nəticə:
| student_name | course_name |
|---|---|
| Otto Song | Mathematics |
| Alex Lin | Mathematics |
Çoxlu JOIN ilə sorğuların optimizasiyası
Böyük cədvəllərlə işləyəndə sorğuların optimizasiyası çox vacib olur. Budur bir neçə məsləhət:
- İndekslərdən istifadə et
İndekslər PostgreSQL-ə daha sürətli işləməyə kömək edir, xüsusilə əsas sütunlar üzrə birləşmələrdə. enrollments cədvəlində student_id və course_id sütunlarında indeks olduğuna əmin ol.
İndeks yaratmaq nümunəsi:
CREATE INDEX idx_enrollments_student_id ON enrollments(student_id);
CREATE INDEX idx_enrollments_course_id ON enrollments(course_id);
İndekslər barədə daha ətraflı növbəti səviyyələrdə öyrənəcəksən, amma burada qeyd etməyə dəyərdi. JOIN-lə çox bağlıdırlar.
- Datani erkən mərhələdə filtrlə
WHERE şərtlərindən istifadə et ki, JOINdan əvvəl işlənəcək sətirlərin sayını azaldasın. Məsələn:
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 = 'İvan Petrov';
- Birləşdiriləcək sətirlərin sayını minimuma endir
İki cədvəldə bütün sətirləri birləşdirməkdənsə, əvvəlcə onları subquery ilə filtrlə:
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;
Və nested SELECT-lər barədə daha ətraflı növbəti səviyyədə öyrənəcəksən :P
Çətin birləşmə nümunəsi: tələbələr, kurslar və fakültələr
Tutaq ki, əlavə bir faculties cədvəlimiz var:
faculties cədvəli:
| id | name |
|---|---|
| 10 | Engineering |
| 20 | Natural Sciences |
courses cədvəli yenilənir:
| id | name | teacher | faculty_id |
|---|---|---|---|
| 101 | Mathematics | Ellen Moore | 10 |
| 102 | Physics | James Okoro | 20 |
| 103 | Computer Science | Nina Delgado | 10 |
Tələbələr, kurslar və fakültələrin siyahısını almaq üçün bir JOIN daha əlavə edirik:
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;
Nəticə:
| student_name | course_name | faculty_name |
|---|---|---|
| Otto Song | Mathematics | Engineering |
| Otto Song | Computer Science | Engineering |
| Maria Chi | Physics | Natural Sciences |
| Alex Lin | Mathematics | Engineering |
Çoxlu JOIN ilə SQL sorğuları bir az çətin görünə bilər, amma onlar güclü hesabatlar qurmağa və dəyərli məlumatlar çıxarmağa imkan verir. Düzgün optimizasiya və strukturla, böyük verilənlər bazası ilə işləmək üçün əla alət olacaq.
GO TO FULL VERSION