فخ WHERE في الربط الخارجي
سبب تحويل تصفية عمود من ربط خارجي داخل WHERE بصمت إلى ربط داخلي
فخ WHERE في الربط الخارجي درس مجاني في Coding Interview Prep على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Coding Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.
الفخ الذي يوقع الجميع
هذا هو أكثر أخطاء outer join شيوعًا التي يضعها المحاوِرون عمدًا: «اعرضوا كل عميل وطلباته من عام 2024، بما في ذلك العملاء الذين ليس لديهم طلبات في 2024.»
يكتب المرشح LEFT JOIN، ثم يضيف عامل تصفية للتاريخ في WHERE، فتختفي بصمت العملاء الذين ليس لديهم طلبات في 2024. وهكذا يتدهور LEFT JOIN بهدوء إلى INNER JOIN. وفهم سبب ذلك مؤشر على مستوى متقدم.
الاستعلام الخاطئ
إليكم الخطأ. يبدو منطقيًا: الاحتفاظ بكل العملاء، وضم طلباتهم، ثم التصفية إلى عام 2024.
لكن العملاء الذين ليس لديهم طلبات، أو ليس لديهم طلبات في 2024، يختفون من النتيجة. وبذلك لا يتحقق شرط تضمينهم.
-- BUG: drops customers with no 2024 order
SELECT c.name, o.id, o.order_date
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.order_date >= '2024-01-01';لماذا يتعطل
تذكّروا ترتيب العمليات: يُنفّذ JOIN أولًا، فينتج صفوفًا تكون فيها قيمة NULL في كل عمود من أعمدة الطلب للعميل غير المتطابق. ثم تُنفّذ WHERE.
بالنسبة إلى عميل غير متطابق، تكون قيمة o.order_date هي NULL، ولذلك يُقيّم الشرط o.order_date >= '2024-01-01' إلى UNKNOWN، وليس true. ولا تُبقي WHERE إلا الصفوف التي تكون نتيجتها true، فتُصفّي صفوف NULL، وهي بالضبط الصفوف التي عمل LEFT JOIN على حفظها.
NULL يُفشل عامل التصفية
تؤدي أي مقارنة مع NULL إلى UNKNOWN: إذ إن NULL >= '2024-01-01' تساوي UNKNOWN، وNULL = 5 تساوي UNKNOWN، وحتى NULL <> 5 تساوي UNKNOWN.
وبما أن WHERE تمرر الصفوف التي تقيّم إلى TRUE فقط، فإن كل صف محفوظ بسبب عدم التطابق يُستبعد. وهكذا يُلغى الغرض الكامل من outer join بسبب شرط واحد في WHERE على عمود من الجدول الأيمن.
الحل: التصفية في ON
انقلوا عامل التصفية إلى عبارة ON. هناك يصبح جزءًا من شرط التطابق ويُطبّق قبل حفظ الصفوف، ولذلك تظل صفوف العملاء غير المتطابقة موجودة مع قيم NULL.
-- CORRECT: filter lives in ON
SELECT c.name, o.id, o.order_date
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id
AND o.order_date >= '2024-01-01';
-- customers with no 2024 order: kept, NULL orderON في مقابل WHERE في جملة واحدة
هذه هي القاعدة التي يمكنكم ترديدها في المقابلة:
بالنسبة إلى الجدول المحفوظ (الجدول الخارجي)، تندرج الشروط على الجدول الآخر ضمن ON؛ أما الشروط على الجدول المحفوظ نفسه فتندرج ضمن WHERE.
- تحدد
ONما يُعد تطابقًا (وتُنفّذ أثناء JOIN). - تُصفّي
WHEREالصفوف النهائية (وتُنفّذ بعده، وتزيل صفوف NULL).
النتائج جنبًا إلى جنب
البيانات نفسها، لكن موضعان مختلفان ونتيجتان مختلفتان. افترضوا أن Carol ليس لديها طلب في 2024.
- عامل التصفية في WHERE: تختفي Carol. ويصبح JOIN فعليًا inner join.
- عامل التصفية في ON: تظهر Carol مرة واحدة مع قيم NULL في أعمدة الطلب، وبذلك يتحقق الشرط.
الاختلاف في الناتج هو جوهر هذا الفخ.
-- ON version output
-- Alice | 50 | 2024-03-01
-- Bob | 20 | 2024-05-02
-- Carol | NULL | NULL <-- preservedمتى يكون WHERE صحيحًا فعلًا
ليست كل عبارة WHERE في outer join خطأ. فتصفية الجدول المحفوظ سليمة؛ لأنها لا تتعامل مع قيم NULL الناتجة عن JOIN.
كما أن anti-join من الدرس السابق يستخدم WHERE o.id IS NULL عن قصد للاستفادة من هذا السلوك تحديدًا. والمهارة تكمن في معرفة الحالة التي تتعاملون معها.
-- Fine: filtering the preserved (left) table
SELECT c.name, o.id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE c.country = 'US';قاعدة الكشف السريع
عند مراجعة outer join، افحصوا عبارة WHERE بحثًا عن شروط على الجدول غير المحفوظ (باستثناء اختبارات anti-join من نوع IS NULL).
إذا رأيتم o.someColumn = ... أو اختبار نطاق أو مساواة على الجانب الخارجي في WHERE، فاشكّوا في وجود الفخ. اسألوا أنفسكم: «هل يحوّل هذا LEFT JOIN لديّ إلى INNER JOIN؟» غالبًا ما تكون الإجابة نعم.
شروط متعددة
يمكنكم الجمع بين الموضعين. فشروط التطابق على الجدول الأيمن توضع في ON، بينما يوضع عامل التصفية الحقيقي بعد JOIN على الجدول الأيسر في WHERE. ويتعايش الموضعان دون مشكلة.
SELECT c.name, o.id, o.amount
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id
AND o.amount > 100 -- match condition
WHERE c.signup_year = 2023; -- preserved-table filterشرح الأمر بصوت عالٍ
في المقابلة، اشرحوا الآلية، لا الحل فقط:
«يُنفّذ JOIN أولًا، ويملأ أعمدة الجهة اليمنى غير المتطابقة بقيم NULL. ويُقيّم شرط WHERE على هذه الأعمدة إلى UNKNOWN في الصفوف التي تحتوي على NULL، كما أن WHERE تستبعد الصفوف التي لا تكون نتيجتها true؛ لذلك ينهار outer join إلى inner join. أما وضع الشرط في ON فيُبقيه شرط تطابق ويحافظ على الصفوف غير المتطابقة.» هذا الشرح ينجح في كل مرة.
تحقق سريع
يجب أن تعرضوا جميع العملاء وطلبات عام 2024 الخاصة بهم فقط، مع الاحتفاظ بالعملاء الذين لم تكن لديهم أي طلبات.
مراجعة
تؤدي تصفية عمود من الجدول غير المحفوظ في WHERE إلى تحويل outer join بصمت إلى inner join، لأن قيم NULL الناتجة عن الصفوف غير المتطابقة تفشل في اجتياز الشرط (فتكون UNKNOWN)، وتزيلها WHERE.
- توضع شروط التطابق على الجدول الخارجي في
ON. - توضع عوامل التصفية على الجدول المحفوظ في
WHERE. - إن استخدام
IS NULLفي WHERE هو anti-join مقصود، وليس الفخ. - اشرحوا ترتيب العمليات لإثبات فهمكم له.
الأسئلة الشائعة
هل درس «فخ WHERE في الربط الخارجي» مجاني؟
نعم — نص درس «فخ WHERE في الربط الخارجي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Coding Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة Coding Interview Prep 4 دروس في المجموع.
ماذا ستتعلم في «فخ WHERE في الربط الخارجي»؟
سبب تحويل تصفية عمود من ربط خارجي داخل WHERE بصمت إلى ربط داخلي تتمرن على Coding Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Coding Interview Prep؟
لا تُشترط خبرة سابقة. Coding Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «فخ WHERE في الربط الخارجي»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Coding Interview Prep هذا؟
نعم. كل درس في Coding Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- LEFT JOIN والحفاظ على الصفوف غير المطابقة
- دلالات RIGHT وFULL OUTER JOIN
- العثور على الصفوف دون تطابق (Anti-Join)
- فخ WHERE في الربط الخارجي