في هذا الدرس 6تصفّح المواضيع
بينما يستبعد الربط الداخلي INNER JOIN أي سجل رئيسي ليس له سجلات فرعية مرتبطة، تتطلب لوحات التقارير غالباً عرض جميع العملاء (حتى من لم يسجل أي طلب) أو جميع المنتجات (حتى التي لم تُبَع بعد). ويضمن الربط الخارجي الأيسر LEFT JOIN (وهو اختصار LEFT OUTER JOIN) بقاء كل صف من الجدول الأيسر المكتوب بعد FROM ضمن النتيجة:
- الصفوف المتطابقة: تُعرض كاملةً مع بياناتها المقابلة من الجدول الأيمن.
- الصفوف غير المتطابقة في اليسار: تبقى في النتيجة النهائية، وتُملأ جميع أعمدة الجدول الأيمن المقابلة لها بالقيمة الفارغة
NULL.
-- Keep all users even if they have never placed an order
SELECT
u.user_id,
u.full_name,
o.order_id,
o.total_amount
FROM users AS u
LEFT JOIN orders AS o
ON u.user_id = o.user_id;
يُعد نمط الاستبعاد الأيسر (Left Anti-Join) من أهم الأنماط الهندسية في SQL؛ إذ يُستخدم لاستخراج السجلات الموجودة في الجدول الأول والتي ليس لها أي سجل مقابل في الجدول الثاني (مثل العملاء المسجلين الذين لم يشتروا مطلقاً، أو المنتجات الراكدة). ويُبنى هذا النمط بدمج LEFT JOIN مع شرط WHERE right_table.primary_key IS NULL:
- لماذا نفحص المفتاح الأساسي للجدول الأيمن؟ لأن المفتاح الأساسي لا يقبل القيمة الفارغة في أي صف حقيقي؛ وبالتالي فإن تحقق الشرط
o.order_id IS NULLيعني قطعاً عدم وجود أي صف مرتبط في الجدول الأيمن.
-- Find customers who have never placed any order (Anti-Join)
SELECT
u.user_id,
u.full_name,
u.email
FROM users AS u
LEFT JOIN orders AS o
ON u.user_id = o.user_id
WHERE o.order_id IS NULL;
يعمل الربط الخارجي الأيمن RIGHT JOIN (أو RIGHT OUTER JOIN) كصورة معكوسة تماماً للربط الأيسر؛ إذ يحتفظ بجميع صفوف الجدول الأيمن المكتوب بعد RIGHT JOIN، ويملأ أعمدة الجدول الأيسر بالقيمة NULL عند غياب التطابق:
- المعيار المهني لقابلية القراءة: يفضّل مهندسو قواعد البيانات عادةً كتابة الاستعلام بصيغة
B LEFT JOIN Aبدلاً منA RIGHT JOIN B، ليبقى الجدول الرئيسي المحتفظ بصفوفه في بداية جملةFROMدائماً.
-- Preserve all departments on the right even with 0 employees
SELECT
d.dept_id,
d.dept_name,
e.emp_name
FROM employees AS e
RIGHT JOIN departments AS d
ON e.dept_id = d.dept_id;
في استعلامات LEFT JOIN، يختلف سلوك الاستعلام جذرياً بحسب موضع كتابة شرط التصفية الخاص بأعمدة الجدول الأيمن بين جملة ON وجملة WHERE:
- وضع الشرط داخل
ON(AND o.status = 'paid'): يُطبَّق الشرط أثناء عملية المطابقة؛ فيبقى جميع المستخدمين في النتيجة، وتُعرض طلباتهم المدفوعة فقط أوNULLإن لم توجد. - وضع الشرط داخل
WHERE(WHERE o.status = 'paid'): يُطبَّق الشرط بعد انتهاء الربط؛ وبما أن مقارنةNULL = 'paid'لا تتحقق، يتم حذف جميع المستخدمين غير المرتبطين، مما يحوّلLEFT JOINبالخطأ إلىINNER JOIN!
-- Filter right-table rows inside ON to preserve all left rows
SELECT
u.user_id,
u.full_name,
o.order_id,
o.total_amount
FROM users AS u
LEFT JOIN orders AS o
ON u.user_id = o.user_id
AND o.status = 'paid';
عند تجميع نتائج LEFT JOIN باستخدام GROUP BY، يقع كثير من المطورين في فخ استدعاء COUNT(*)؛ فبما أن السجل الأيسر غير المرتبط يظل ممثلاً بصف واحد في النتيجة (مع قيم NULL في اليمين)، فإن COUNT(*) يحسب ذلك الصف ويعطي 1 بدلاً من 0! التزم دائماً بالقاعدتين التاليتين:
- استخدم
COUNT(right_table.pk): مرّر عمود المفتاح الأساسي للجدول الأيمن (COUNT(o.order_id)) ليتجاهل قيمNULLويرجع0بدقة. - غلّف المجاميع بدالة
COALESCE: استخدمCOALESCE(SUM(o.total_amount), 0.00)لتحويل المجموع الفارغ إلى صفر رقمي نظيف.
-- Count right-table PK and coalesce NULL sums to zero
SELECT
u.user_id,
u.full_name,
COUNT(o.order_id) AS orders_count,
COALESCE(SUM(o.total_amount), 0.00) AS total_spent
FROM users AS u
LEFT JOIN orders AS o ON u.user_id = o.user_id
GROUP BY u.user_id, u.full_name;
يقارن الجدول التالي بين سلوك الربط الداخلي وأنواع الربط الخارجي في MySQL 8:
| نوع الربط | صفوف اليسار غير المتطابقة | صفوف اليمين غير المتطابقة | حالة الاستخدام الهندسي المثلى |
|---|---|---|---|
INNER JOIN | تُستبعد | تُستبعد | استرجاع التقاطع الصارم للسجلات الموجودة في الجدولين معاً |
LEFT JOIN | تبقى (واليمين NULL) | تُستبعد | تقارير تعرض جميع السجلات الرئيسية حتى لو لم تملك سجلات فرعية |
LEFT JOIN ... WHERE r.pk IS NULL | تبقى وحدها فقط | تُستبعد | نمط Anti-Join لاكتشاف السجلات التي لا تملك أي ارتباط |
RIGHT JOIN | تُستبعد | تبقى (واليسار NULL) | الاحتفاظ بصفوف الجدول الثاني (ويُفضّل كتابتها بـ LEFT JOIN) |
ملخص الدرس: تعرّفنا في هذا الدرس على آلية عمل LEFT JOIN وRIGHT JOIN للاحتفاظ بالسجلات غير المتطابقة، ونمط IS NULL لاكتشاف السجلات المفقودة، والفرق الحاسم بين وضع شروط الجدول الأيمن في ON مقابل WHERE، والعد الصحيح عبر COUNT(right.pk).
الخطوة التالية والدرس القادم: في الدرس القادم سندرس «الربط التبادلي CROSS JOIN والربط الذاتي SELF JOIN في MySQL» لتوليد التوافيق واستعراض الجداول الهرمية.
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
يضمن LEFT JOIN الاحتفاظ بجميع صفوف الجدول الرئيسي ويمكّنك من بناء استعلامات Anti-Join والتجميع الدقيق عبر COUNT(right.pk). الخطوة التالية: انتقل إلى درس «الربط التبادلي CROSS JOIN والربط الذاتي SELF JOIN في MySQL».
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات5
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 Outer Joins الربط الخارجي
- تعلّم الربط الخارجي LEFT JOIN و RIGHT JOIN في MySQL بأسلوب MySQL 8 الحديث مع أمثلة استعلامات SQL وتطبيقات تفاعلية.
- للمراجعة
- 02 Preserving Unmatched Rows LEFT JOIN الربط الخارجي الأيسر LEFT JOIN
- المفهوم الهندسي والصياغة العملية الخاصة بقسم الربط الخارجي الأيسر LEFT JOIN في MySQL 8.
- للمراجعة
- 03 Finding Missing Records Anti Join اكتشاف السجلات غير المرتبطة
- المفهوم الهندسي والصياغة العملية الخاصة بقسم اكتشاف السجلات غير المرتبطة في MySQL 8.
- للمراجعة
- 04 Right Table Preservation RIGHT JOIN الربط الخارجي الأيمن RIGHT JOIN
- المفهوم الهندسي والصياغة العملية الخاصة بقسم الربط الخارجي الأيمن RIGHT JOIN في MySQL 8.
- للمراجعة
- 05 ON vs WHERE Join Condition شرط الربط ON مقابل WHERE
- المفهوم الهندسي والصياغة العملية الخاصة بقسم شرط الربط ON مقابل WHERE في MySQL 8.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات2
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 LEFT JOIN LEFT JOIN
- Left Outer Join
- ربط خارجي يحتفظ بجميع صفوف الجدول الأيسر ويملأ أعمدة الجدول الأيمن غير المتطابقة بالقيمة NULL.
- للمراجعة
- 02 ANTI-JOIN ANTI-JOIN
- Relational Anti-Semi-Join Pattern
- نمط استعلام يرجع صفوف الجدول الأيسر التي لا تملك أي صف مطابق في الجدول الأيمن.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
نفّذ أمثلة SQL المشروحة في قسم الربط الخارجي الأيسر LEFT JOIN داخل قاعدة بياناتك المحلية وتحقق من مجموعة النتائج.
-
بدّل بين الحالات التفاعلية في قسم اكتشاف السجلات غير المرتبطة وقارن كيف ينفّذ محرك MySQL 8 كل استعلام.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي5 أسئلة تنتظرك +
عند تنفيذ LEFT JOIN بين جدول المستخدمين (يساراً) وجدول الطلبات (يميناً)، ماذا يظهر في أعمدة الطلبات للمستخدم الذي لم يسجل أي طلب؟
تذكّر كيف يتعامل LEFT JOIN مع أعمدة الجدول الأيمن عند عدم وجود تطابق.
ما هو شرط WHERE الذي يكمل نمط Anti-Join مع LEFT JOIN لاستخراج المستخدمين الذين ليس لديهم أي طلبات؟
افحص المفتاح الأساسي للجدول الأيمن للتأكد من كونه فارغاً NULL.
ماذا يحدث إذا كتبت LEFT JOIN orders o ON u.id = o.user_id ثم أضفت الشرط WHERE o.status = 'paid'؟
فكّر كيف يتعامل شرط WHERE مع القيم الفارغة NULL في أعمدة الجدول الأيمن.
عند حساب عدد الطلبات لكل عميل في استعلام LEFT JOIN، لماذا يجب استخدام COUNT(o.order_id) بدلاً من COUNT(*)؟
قارن بين تعامل COUNT(*) وCOUNT(column) مع الصف الذي يحتوي على NULL في الجانب الأيمن.
يمكن إعادة كتابة أي استعلام RIGHT JOIN إلى استعلام LEFT JOIN مكافئ تماماً عن طريق عكس ترتيب الجدولين.
تذكّر العلاقة التناظرية بين الربط الأيسر والربط الأيمن.