لماذا يعيد EXISTS جميع العملاء عند نسيان شرط الربط؟

متوسطقراءة دقيقةآخر تحديث 3 أكتوبر 2026

SQL قواعد البيانات

الإجابة

لا يصبح الاستعلام الفرعي مترابطًا لمجرد وضعه داخل استعلام آخر. يجب أن يحتوي على مرجع فعلي إلى الصف الخارجي. إذا كتبت اختبار وجود طلب مدفوع دون ربط الطلب بالعميل، فأنت تسأل عن وجود طلب مدفوع في الجدول كله، وليس عن وجوده للعميل الحالي.

ينتج عن هذا الخطأ سلوك قد يبدو صحيحًا مع بيانات صغيرة ثم يفشل لاحقًا. بمجرد وجود طلب مدفوع واحد لأي عميل، يصبح الشرط غير المترابط متحققًا لكل العملاء. وإذا لم توجد طلبات مدفوعة، يرفض الشرط جميعهم. لا تستطيع إضافة DISTINCT تصحيح هذا المعنى، لأنها تعالج تكرار النتائج فقط.

مثال

WITH customers AS (
  SELECT 1 AS id UNION ALL SELECT 2
), orders AS (
  SELECT 1 AS customer_id, 'paid' AS status
)
SELECT c.id
FROM customers AS c
WHERE EXISTS (
  SELECT 1 FROM orders AS o
  WHERE o.customer_id = c.id
    AND o.status = 'paid'
);

استخدام أسماء مستعارة واضحة يجعل مراجعة شرط الربط أسهل، ويساعد على اكتشاف المقارنات التي لا تشير إلى الصف الخارجي.

باختصار: أضف شرط العلاقة داخل EXISTS عندما يكون المطلوب فحص وجود بيانات تخص كل صف خارجي.

هل تريد تعلّم SQL خطوة بخطوة مع تمارين عملية؟ تابع مسار SQL من الأساسيات للاحتراف.

اختبر فهمك

ما التعديل الذي يجعل الاستعلام يختار فقط العملاء الذين لديهم طلب مدفوع؟

SELECT c.id
FROM customers AS c
WHERE EXISTS (
  SELECT 1
  FROM orders AS o
  WHERE o.status = 'paid'
);