LEFT ба RIGHT JOIN
INNER JOIN нь хоёр хүснэгтэд хоёуланд нь таарах бичлэгийг л буцаадаг байсан. Гэхдээ заримдаа нэг талд таарахгүй байсан ч бүх бичлэгийг харах хэрэгтэй болдог — жишээ нь "нийтлэл нийтлэж байгаагүй зохиогчдыг ч оруулж харах." LEFT JOIN ба RIGHT JOIN яг энэ тохиолдолд хэрэглэнэ.
LEFT JOIN — зүүн хүснэгтийн бүгдийг хадгална
LEFT JOIN нь зүүн (FROM-ийн) хүснэгтийн БҮГД бичлэгийг буцаана. Баруун хүснэгтэд таарахгүй бол тухайн баганад NULL гарна.
Өмнөх authors ба posts жишээнд буцъя:
authors — 3 зохиогч (Болд, Сарнай, Ганбаяр) posts — зөвхөн Болд ба Сарнай нийтлэлтэй, Ганбаяр нийтлэлгүй
SELECT
a.нэр AS зохиогч,
p.гарчиг AS нийтлэл
FROM authors AS a
LEFT JOIN posts AS p ON p.author_id = a.id;
зохиогч | нийтлэл
-----------+--------------------
Болд | SQL суурь
Болд | JOIN тайлбар
Сарнай | Index гэж юу вэ
Ганбаяр | NULL
Ганбаяр нийтлэлгүй ч жагсаалтад гарч ирлээ — нийтлэл нь NULL болсон.
NULL-г ашиглан "таарахгүй" бичлэг олох
LEFT JOIN-ны хамгийн хүчирхэг хэрэглээ бол нэг хүснэгтэд байгаагүй бичлэгүүдийг олох явдал юм:
-- Нийтлэл огт нийтлээгүй зохиогчдыг ол
SELECT a.нэр, a.имэйл
FROM authors AS a
LEFT JOIN posts AS p ON p.author_id = a.id
WHERE p.id IS NULL;
нэр | имэйл
-----------+---------------------
Ганбаяр | ganbayar@example.com
WHERE p.id IS NULL гэдэг нь "баруун хүснэгтэд таарахгүй байсан" гэсэн утга — энэ загварыг anti-join гэж нэрлэдэг. Маш их хэрэглэгддэг!
LEFT JOIN-ны нийтлэг хэрэглээ
-- Бүх хэрэглэгч ба тэдний хамгийн сүүлийн захиалга (захиалгагүй бол NULL)
SELECT
u.нэр,
u.имэйл,
MAX(o.үүсгэсэн) AS сүүлийн_захиалга
FROM users AS u
LEFT JOIN orders AS o ON o.user_id = u.id
GROUP BY u.id, u.нэр, u.имэйл
ORDER BY сүүлийн_захиалга DESC NULLS LAST;
-- Бүх курс ба тухайн хэрэглэгчийн гүйцэтгэлийн хувь (бүртгэлгүй бол NULL)
SELECT
c.гарчиг AS курс,
lp.дууссан_хичээл,
c.нийт_хичээл
FROM courses AS c
LEFT JOIN (
SELECT course_id, COUNT(*) AS дууссан_хичээл
FROM lesson_progress
WHERE user_id = 1
GROUP BY course_id
) AS lp ON lp.course_id = c.id
ORDER BY c.id;
RIGHT JOIN — баруун хүснэгтийн бүгдийг хадгална
RIGHT JOIN нь LEFT JOIN-ны эсрэг — баруун (JOIN-ны) хүснэгтийн БҮГД бичлэгийг буцаана. Зүүн хүснэгтэд таарахгүй бол NULL гарна:
SELECT
a.нэр AS зохиогч,
p.гарчиг AS нийтлэл
FROM posts AS p
RIGHT JOIN authors AS a ON p.author_id = a.id;
Энэ нь өмнөх LEFT JOIN-тэй яг адил үр дүн өгнө — хүснэгтүүдийн байрлалыг эсрэгээр бичсэн учраас.
Практик дээр RIGHT JOIN-г LEFT JOIN-аар бичин ойлгомжтой болгох нь нийтлэг дадал:
-- RIGHT JOIN ашиглан
SELECT a.нэр, p.гарчиг
FROM posts AS p
RIGHT JOIN authors AS a ON p.author_id = a.id;
-- Яг адил, гэхдээ LEFT JOIN илүү ойлгомжтой
SELECT a.нэр, p.гарчиг
FROM authors AS a
LEFT JOIN posts AS p ON p.author_id = a.id;
Ихэнх хөгжүүлэгчид RIGHT JOIN-г ховор ашигладаг — LEFT JOIN-аар дахин бичиж болдог учраас.
Олон LEFT JOIN хослуулах
-- Курс бүрийн мэдээллийг, хэрэглэгч бүртгэлтэй эсэх ба дууссан хичээлийн тоотой
SELECT
c.гарчиг AS курс,
c.нийт_хичээл,
e.бүртгэсэн_огноо,
COUNT(lp.id) AS дууссан
FROM courses AS c
LEFT JOIN enrollments AS e ON e.course_id = c.id AND e.user_id = 5
LEFT JOIN lesson_progress AS lp ON lp.course_id = c.id AND lp.user_id = 5
GROUP BY c.id, c.гарчиг, c.нийт_хичээл, e.бүртгэсэн_огноо
ORDER BY c.id;
LEFT JOIN vs INNER JOIN — хэзээ алийг сонгох вэ?
| Асуулт | JOIN сонголт |
|--------|-------------|
| Хоёр хүснэгтэд хоёуланд нь байгаа бичлэгийг л хар | INNER JOIN |
| Нэг талын бүгдийг, нөгөө талынхыг байвал нь хамт хар | LEFT JOIN |
| Таарахгүй байгаа бичлэгийг ол | LEFT JOIN ... WHERE нөгөө.id IS NULL |
Дүрэм болгон: "бүх ... + байвал нь ..." гэж бодвол LEFT JOIN. Жишээ нь "бүх хэрэглэгч + тэдний захиалга байвал нь" → LEFT JOIN.
Дараагийн хичээлд:
FULL OUTER JOIN ба CROSS JOIN-г сурна — хоёр хүснэгтийн бүгдийг нэгэн зэрэг харах ба Декартын үржвэр гэх дэвшилтэт загваруудыг ойлгоно.