الربط المضاد والربط شبه الكامل (NOT EXISTS)
اعثر على «الصفوف في A التي لا تطابقها صفوف في B» وعلى «الصفوف في A التي لها تطابق واحد على الأقل في B» باستخدام EXISTS وNOT EXISTS.
الربط المضاد والربط شبه الكامل (NOT EXISTS) درس مجاني في SQL Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Academy 4 دروس في المجموع.
Semi-Join: «يحتوي على تطابق واحد على الأقل»
أرجع الصفوف من A التي تحتوي على صف مطابق واحد على الأقل في B — ولكن أعمدة A فقط. تطبق SQL عمليات semi-join باستخدام EXISTS أو IN.
EXISTS Semi-Join
المستخدمون الذين أجروا طلباً واحداً على الأقل:
SELECT u.* FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o WHERE o.user_id = u.id
);IN Semi-Join
النتيجة نفسها، لكن بأسلوب مختلف:
SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders);لماذا يتفوق EXISTS غالباً
يتوقف EXISTS مبكراً، إذ يتوقف عند أول تطابق لكل صف خارجي. وقد ينشئ IN مجموعة البيانات الداخلية كاملة في الذاكرة. غالباً ما تحسّن المخططات الحديثة الاستعلامين إلى الخطة نفسها، لكن EXISTS خيار أكثر أماناً مع المجموعات الداخلية الضخمة.
Anti-Join: «لا يحتوي على تطابق»
المستخدمون الذين لم يجروا أي طلب على الإطلاق — ثلاث صيغ اصطلاحية:
-- NOT EXISTS (preferred):
SELECT u.* FROM users u
WHERE NOT EXISTS (
SELECT 1 FROM orders o WHERE o.user_id = u.id
);
-- LEFT JOIN ... IS NULL:
SELECT u.* FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.id IS NULL;
-- NOT IN (risky with NULLs):
SELECT * FROM users WHERE id NOT IN (SELECT user_id FROM orders);لماذا يُعد NOT IN محفوفاً بالمخاطر
إذا احتوى الاستعلام الفرعي الداخلي على NULL، يُرجع NOT IN القيمة NULL — وتحذف WHERE الصفوف التي تكون فيها المسندة NULL. والنتيجة: لا توجد صفوف. لا يواجه NOT EXISTS هذه المشكلة.
تحسين المخطط
يتعرف PostgreSQL الحديث على EXISTS وNOT EXISTS كأنماط semi-join وanti-join، وقد ينفذهما باستخدام وصلات التجزئة:
EXPLAIN ANALYZE
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
-- → Hash Anti JoinAnti-Joins متعددة الأعمدة
استخدم مفاتيح مركبة:
SELECT * FROM order_items oi
WHERE NOT EXISTS (
SELECT 1 FROM shipments s
WHERE s.order_id = oi.order_id
AND s.line_no = oi.line_no
);Semi-Join باستخدام EXISTS + مسند إضافي
أضف عوامل تصفية إلى الاستعلام الفرعي الداخلي:
SELECT u.* FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.user_id = u.id
AND o.status = 'paid'
AND o.created_at >= NOW() - INTERVAL '30 days'
);فهرسة عمود الارتباط
في كل من EXISTS وNOT EXISTS، يرشّح الاستعلام الفرعي الداخلي باستخدام مفتاح الصف الخارجي. ومن دون فهرس على هذا المفتاح، ستحصل على عملية مسح لكل صف خارجي:
CREATE INDEX orders_user_id_idx ON orders(user_id);متى تستخدم LEFT JOIN ... IS NULL
بالنسبة إلى لوحات المعلومات التي تحتاج أيضاً إلى أعمدة الجانب غير المطابق، تناسبها صيغة LEFT JOIN طبيعياً. أما بالنسبة إلى دلالات anti-join الخالصة، فـNOT EXISTS أوضح.
ما وراء SQL: مرشحات Bloom
بالنسبة إلى عمليات anti-join الضخمة، قد يساعد مرشح Bloom تمهيدي. تدعم PostgreSQL فهارس bloom عبر إضافة bloom.
خلاصة
Semi-join = «يحتوي على تطابق»؛ وanti-join = «لا يحتوي على تطابق».
- استخدم EXISTS لعملية semi-join
- استخدم NOT EXISTS لعملية anti-join، فهو آمن مع NULL
- فهرس عمود الارتباط
- تجنب NOT IN ما لم يكن من المستحيل أن يحتوي الجزء الداخلي على NULL
تحقق سريع
تريد المستخدمين الذين لم يجروا أي طلب على الإطلاق. ما صيغة SQL الأكثر أماناً وشيوعاً؟
الأسئلة الشائعة
هل درس «الربط المضاد والربط شبه الكامل (NOT EXISTS)» مجاني؟
نعم — نص درس «الربط المضاد والربط شبه الكامل (NOT EXISTS)» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Academy، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Academy 4 دروس في المجموع.
ماذا ستتعلم في «الربط المضاد والربط شبه الكامل (NOT EXISTS)»؟
اعثر على «الصفوف في A التي لا تطابقها صفوف في B» وعلى «الصفوف في A التي لها تطابق واحد على الأقل في B» باستخدام EXISTS وNOT EXISTS. تتمرن على SQL Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ SQL Academy؟
لا تُشترط خبرة سابقة. SQL Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «الربط المضاد والربط شبه الكامل (NOT EXISTS)»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس SQL Academy هذا؟
نعم. كل درس في SQL Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- عمليات Cross Join والمنتجات الديكارتية
- عمليات الربط الجانبي (LATERAL JOIN)
- الربط المضاد والربط شبه الكامل (NOT EXISTS)
- ضبط أداء الربط بين جداول متعددة