CodeGym /Kurslar /SQL SELF /JOIN istifadə edəndə tipik səhvlər

JOIN istifadə edəndə tipik səhvlər

SQL SELF
Səviyyə , Dərs
Mövcuddur

İndi gəlin bir az həyatdan danışaq. O tərəfdən ki, ondan qaçmaq olmur: səhvlər. Səhvləri tutmaq, düzəltmək və başa düşmək — data ilə işləməyin vacib hissəsidir. Gəlin baxaq, SQL-də JOIN ilə işləyərkən hansı "qraplilərə" düşürük və onlardan necə yan keçmək olar.

Səhv 1: Birləşmə şərtini unutmaq — dekart hasili yaratmaq

Ən çox rast gəlinən səhv — ON istifadə edərkən birləşmə şərtini göstərməyi unutmaqdır. Bu halda dekart hasili yaranır, yəni birinci cədvəldəki hər sətr ikinci cədvəldəki hər sətr ilə birləşir. Nəticədə, heç bir məna kəsb etməyən və səni çaşdıran tonlarla sətir alırsan.

Misal gətirək. Tutaq ki, bizdə belə cədvəllər var:

Tələbələr (students):

student_id name
1 Otto
2 Anna

Kurslar (courses):

course_id course_name
101 Riyaziyyat
102 Tarix

İndi ON olmadan sorğu yazaq:

SELECT *
FROM students
JOIN courses;

Nəticə:

student_id name course_id course_name
1 Otto 101 Riyaziyyat
1 Otto 102 Tarix
2 Anna 101 Riyaziyyat
2 Anna 102 Tarix

Bu, real görünmür, düzdür? Bu kabus dekart hasili adlanır.

Necə düzəltmək olar: ON istifadə et, cədvəllərdəki dataların necə bağlı olduğunu göstər.

SELECT *
FROM students
JOIN courses
ON students.student_id = courses.course_id;

Və burada yeni səhv fəsli başlayır...

Axmaqdan qorunma

Bu o qədər yayılmış problemdir ki, PostgreSQL-də JOIN şərtsiz və ON olmadan istifadəsini qadağan ediblər.

Əgər sənə hər sətri hər sətirlə birləşdirmək lazımdırsa, JOIN olmadan belə sintaksis istifadə edə bilərsən:

SELECT *
FROM students, courses;

Başqa bir variant - JOIN ON olmadan işləyəndə:

  • NATURAL JOIN ilə — avtomatik olaraq eyni adlı sütunları birləşdirir.
  • USING ilə — birləşdirilən sütunların siyahısını göstərirsən.
  • CROSS JOIN — həmişə şərtsizdir, yəni dekart hasilinin özü.

Səhv 2: Yanlış birləşmə şərti

Bəzən birləşmə şərtini göstərirsən, amma səhv edirsən. Məsələn, cədvəlləri açarlarla yox, əlaqəsiz datalarla birləşdirirsən.

Tutaq ki, tələbələrin və onların yazıldığı kursların siyahısını almaq istəyirik, amma səhv edib əlaqəsiz sahələr üzrə birləşdiririk:

SELECT *
FROM students
JOIN courses
ON students.student_id = courses.course_id;

Belə sorğu səhv nəticə verəcək, çünki student_idcourse_id — tamamilə fərqli şeylərdir.

Necə düzəltmək olar: düzgün sütunlardan istifadə etdiyinə əmin ol. Düzgün birləşmə belə ola bilər (əgər tələbələri kurslarla birləşdirən enrollments cədvəlin varsa):

SELECT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

Səhv 3: Nəticədə sətrlərin təkrarlanması

Sorğuda bir neçə JOIN əlavə edəndə bəzən sətrlər təkrarlanır. Bu, JOIN olunan cədvəllərdə təkrarlanan yazılar olduqda və ya birləşmə şərtlərini səhv göstərdikdə baş verir.

Tutaq ki, Otto adlı tələbə enrollments cədvəlində eyni kursa iki dəfə yazılıb.

enrollments cədvəlində yazılar:

student_id course_id
1 101
1 101

İndi JOIN ilə sorğu belə nəticə verəcək:

SELECT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

Nəticə:

name course_name
Otto Riyaziyyat
Otto Riyaziyyat

Necə düzəltmək olar: birincisi, cədvəllərində təkrarlanan dataların olmadığından əmin ol. İkincisi, əgər bu gözlənilən davranışdırsa, təkrarlananları DISTINCT ilə sil:

SELECT DISTINCT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

Səhv 4: INNER JOIN istifadə edəndə sətrlərin itməsi

INNER JOIN yalnız hər iki cədvəldə uyğun gələn sətrləri qaytarır. Əgər bir cədvəldə uyğun dəyər yoxdursa, sətir atılacaq. Yanlış birləşmə növü seçsən, data itirə bilərsən.

Tutaq ki, bizdə hələ heç bir kursa yazılmamış tələbə var:

Tələbələr (students):

student_id name
1 Otto
2 Anna
3 Dhany

Yazılar (enrollments):

student_id course_id
1 101
2 102

İndi INNER JOIN ilə sorğu:

SELECT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

Nəticə:

name course_name
Otto Riyaziyyat
Anna Tarix

Bəs Dhany haradadır? Əgər kursu olmayan tələbələri də görmək istəyirsənsə, LEFT JOIN istifadə et:

SELECT students.name, courses.course_name
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id;

Səhv 5: NULL dəyərləri düzgün işləməmək

Əgər cədvəldə boş (NULL) dəyərlər varsa, onlar nəticədən kənarda qala bilər (məsələn, filtrasiya şərtləri istifadə edəndə).

Misal: LEFT JOIN istifadə edirsən, amma sonra WHERE ilə filtrasiya əlavə edirsən.

SELECT students.name, courses.course_name
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id
WHERE courses.course_name = 'Riyaziyyat';

İndi kursu olmayan tələbələr nəticəyə düşməyəcək, baxmayaraq ki, LEFT JOIN istifadə etmisən.

Necə düzəltmək olar: əgər kursu olmayan sətrləri də daxil etmək istəyirsənsə, WHERE əvəzinə ON istifadə et və ya əlavə şərt əlavə et:

SELECT students.name, courses.course_name
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id
WHERE courses.course_name IS NULL OR courses.course_name = 'Riyaziyyat';

Səhv 6: Birləşmə növləri arasında qarışıqlıq

Hansı birləşmə növünü istifadə edəcəyini qarışdırırsan. Məsələn, RIGHT JOIN istifadə edirsən, halbuki sadəcə cədvəllərin sırasını dəyişməklə LEFT JOIN istifadə etmək olardı.

Qarışıqlıqdan necə qaçmaq olar:

  • İmkan varsa, LEFT JOIN istifadə et. Bu, daha intuitivdir.
  • RIGHT JOIN lazım olmasın deyə cədvəllərin sırasını dəyiş.
1
Sorğu/viktorina
, səviyyə, dərs
Əlçatan deyil
Çoxsaylı JOIN-lar
Çoxsaylı JOIN-lar
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION