انتقل إلى محتوى الدرس
الدرس 47
دورة MySQL

الاستعلامات الفرعية المترابطة ومعامل EXISTS في MySQLMySQL Correlated Subqueries and EXISTS Operator

تعلّم الاستعلامات الفرعية المترابطة ومعامل EXISTS في MySQL بأسلوب MySQL 8 الحديث مع أمثلة استعلامات SQL وتطبيقات تفاعلية.
أقسام الدرس
6
الأمثلة
5
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
8
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

في الدرس السابق، كانت الاستعلامات الفرعية مستقلة غير مترابطة؛ إذ ينفّذ المحرك الاستعلام الداخلي مرة واحدة بمعزل عن الخارجي. أما الاستعلام الفرعي المترابط (Correlated Subquery) فيشير داخله إلى عمود أو أكثر من جدول معرّف في الاستعلام الخارجي:

  • الارتباط بالاسم المستعار الخارجي: نظراً لاعتماد جملة WHERE الداخلية على اسم مستعار خارجي (مثل WHERE o.user_id = u.user_id)، لا يمكن تشغيل الاستعلام الداخلي بمفرده.
  • التقييم المنطقي لكل صف: منطقياً، تُقيّم نتيجة الاستعلام الداخلي نسبةً إلى كل صف مرشح يفحصه الاستعلام الخارجي.
مخطط الاستعلامات الفرعية المترابطة ومعاملي EXISTS و NOT EXISTS في MySQL 8
SQL
-- Fetch each customer along with their latest order date
SELECT
  u.user_id,
  u.full_name,
  (
    SELECT MAX(o.order_date)
    FROM orders AS o
    WHERE o.user_id = u.user_id
  ) AS last_order_date
FROM users AS u;

من أشهر الأنماط التحليلية للاستعلام الفرعي المترابط مقارنة كل صف بمتوسط أو أعلى قيمة داخل مجموعته الخاصة؛ مثل استخراج الموظفين الذين يتجاوز راتبهم متوسط رواتب قسمهم، أو المنتجات الأعلى سعراً من متوسط فئتها:

  • اسمان مستعاران لنفس الجدول: امنح الجدول الخارجي الاسم المستعار p1 والجدول الداخلي الاسم المستعار p2.
  • شرط ربط المجموعة: اربط دالة التجميع الداخلية بفئة الصف الخارجي الحالي عبر الشرط WHERE p2.category_id = p1.category_id.
SQL
-- Find products priced higher than their own category average
SELECT
  p1.product_id,
  p1.category_id,
  p1.product_title,
  p1.unit_price
FROM products AS p1
WHERE p1.unit_price > (
  SELECT AVG(p2.unit_price)
  FROM products AS p2
  WHERE p2.category_id = p1.category_id
);

عندما تحتاج فقط إلى التحقق من وجود سجل مرتبط واحد على الأقل في جدول آخر دون الحاجة لجلب أعمدته، استخدم المعامل المنطقي EXISTS (subquery):

  • التوقف المبكر السريع (Short-Circuit): بمجرد عثور محرك InnoDB على أول صف مطابق في الجدول الداخلي، يرجع المعامل EXISTS القيمة TRUE فوراً ويتوقف عن فحص بقية الصفوف المطابقة لذلك المفتاح.
  • اصطلاح SELECT 1: لأن EXISTS لا ينظر إلى قيم الأعمدة المختارة بل يفحص وجود الصف فقط، يَكتفي المطورون بكتابة SELECT 1 داخل الاستعلام الفرعي.
SQL
-- Find customers who have placed at least one paid order
SELECT
  u.user_id,
  u.full_name,
  u.email
FROM users AS u
WHERE EXISTS (
  SELECT 1
  FROM orders AS o
  WHERE o.user_id = u.user_id
    AND o.status = 'paid'
);

عند البحث عن السجلات غير المرتبطة، يُعد الاختيار بين NOT EXISTS وNOT IN قراراً حاسماً لسلامة النتائج متى كان العمود الداخلي يقبل القيمة الفارغة NULL:

  • تعطل NOT IN بوجود NULL: إذا كان العمود orders.user_id يقبل NULL (للطلبات كضيف) ووجد صف واحد فارغ، فإن NOT IN (SELECT user_id FROM orders) يرجع صفراً من الصفوف دائماً.
  • أمان NOT EXISTS التام مع الفارغ: لأن EXISTS يفحص فقط هل أرجع الشرط o.user_id = u.user_id صفاً فعلياً أم لا، فإن NOT EXISTS لا يتأثر أبداً بوجود قيم NULL في الجدول الداخلي.
SQL
-- Null-safe check for customers without orders even if guest NULLs exist
SELECT
  u.user_id,
  u.full_name
FROM users AS u
WHERE NOT EXISTS (
  SELECT 1
  FROM orders AS o
  WHERE o.user_id = u.user_id
);

يقارن الجدول التالي بين أنماط الاستعلامات المترابطة ومعامل EXISTS والربط في MySQL 8:

نمط الاستعلامهل يكرر صفوف الجدول الخارجي؟الأمان مع قيم NULL الداخليةالسيناريو الهندسي الأمثل
WHERE EXISTS (SELECT 1 ...)لا يكرر الصفوف أبداًآمن 100% مع NULLفحص وجود سجلات فرعية دون الحاجة لعرض أعمدة الجدول الداخلي
WHERE NOT EXISTS (SELECT 1 ...)لا يكرر الصفوف أبداًآمن 100% مع NULLاستخراج السجلات التي لا تملك أي ارتباط في الجدول الفرعي
WHERE col NOT IN (SELECT ...)لا يكرر الصفوفيفشل ويرجع 0 صفوف بوجود NULLيُتجنب مع الاستعلامات الفرعية التي قد تحتوي على NULL
INNER JOIN / LEFT JOINيكرر الصف بعدد التطابقات الفرعيةآمن في شرط ONعند الحاجة لعرض أو تجميع أعمدة من كلا الجدولين معاً

ملخص الدرس: فرّقنا في هذا الدرس بين الاستعلام الفرعي المستقل والمترابط، وقارنّا كل صف بمتوسط فئته، واستخدمنا EXISTS للفحص السريع، ووضحنا سبب تفوق NOT EXISTS على NOT IN بوجود القيم الفارغة.
الخطوة التالية والدرس القادم: في الدرس القادم سندرس «التعبيرات الجدولية الشائعة WITH والاستعلامات العودية في MySQL».

خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

توفر الاستعلامات المترابطة ومعاملا EXISTS وNOT EXISTS مقارنات دقيقة داخل المجموعات وفحصاً آمناً للوجود والغياب دون تكرار الصفوف. الخطوة التالية: انتقل إلى درس «التعبيرات الجدولية الشائعة WITH والاستعلامات العودية في MySQL».

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات5

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 5 مفهومةأول بطاقة، أول خطوة
01 EXISTS Queries معامل EXISTS
تعلّم الاستعلامات الفرعية المترابطة ومعامل EXISTS في MySQL بأسلوب MySQL 8 الحديث مع أمثلة استعلامات SQL وتطبيقات تفاعلية.
للمراجعة
02 Independent vs Correlated Subqueries الاستعلام المستقل مقابل المترابط
المفهوم الهندسي والصياغة العملية الخاصة بقسم الاستعلام المستقل مقابل المترابط في MySQL 8.
للمراجعة
03 Row by Row Benchmark Comparisons مقارنة الصف بمتوسط مجموعته
المفهوم الهندسي والصياغة العملية الخاصة بقسم مقارنة الصف بمتوسط مجموعته في MySQL 8.
للمراجعة
04 Short Circuit Check with EXISTS فحص الوجود السريع بـ EXISTS
المفهوم الهندسي والصياغة العملية الخاصة بقسم فحص الوجود السريع بـ EXISTS في MySQL 8.
للمراجعة
05 Finding Missing Links NOT EXISTS اكتشاف الغياب بـ NOT EXISTS
المفهوم الهندسي والصياغة العملية الخاصة بقسم اكتشاف الغياب بـ NOT EXISTS في MySQL 8.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات3

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 3 مفهومةأول بطاقة، أول خطوة
01 EXISTS EXISTS
Short-Circuit Subquery Existence Operator
معامل منطقي يرجع صواب فور عثور الاستعلام الفرعي المترابط على صف واحد مطابق على الأقل.
للمراجعة
02 Anti-Join ربط الاستبعاد
Relational Anti-Semi-Join
عملية علائقية تستخرج صفوف الجدول الخارجي التي لا تملك أي تطابق في الجدول الداخلي.
للمراجعة
03 3VL منطق ثلاثي القيم
SQL Three-Valued Logic (TRUE, FALSE, UNKNOWN)
النظام المنطقي في SQL الذي يفسر سبب تعطل NOT IN عند وجود قيم NULL.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. نفّذ أمثلة SQL المشروحة في قسم الاستعلام المستقل مقابل المترابط داخل قاعدة بياناتك المحلية وتحقق من مجموعة النتائج.

  2. بدّل بين الحالات التفاعلية في قسم مقارنة الصف بمتوسط مجموعته وقارن كيف ينفّذ محرك MySQL 8 كل استعلام.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

5أسئلة 2أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي5 أسئلة تنتظرك
01

ما الذي يميز الاستعلام الفرعي المترابط عن الاستعلام الفرعي المستقل في MySQL؟

ركّز على علاقة الاستعلام الداخلي بأعمدة الاستعلام الخارجي.

02

في الشرط WHERE p1.unit_price > (SELECT AVG(p2.unit_price) FROM products AS p2 WHERE p2.category_id = p1.category_id)، ماذا يرجع الاستعلام؟

حلّل معنى ربط رقم الفئة الداخلي برقم فئة المنتج الخارجي.

03

عند تنفيذ WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.user_id)، يتوقف MySQL عن فحص بقية طلبات ذلك العميل فور العثور على أول طلب مطابق.

تحقق من خاصية التوقف المبكر السريع في معامل EXISTS.

04

لماذا يُفضّل استخدام WHERE NOT EXISTS (...) بشدة على WHERE user_id NOT IN (SELECT user_id FROM orders) عندما يقبل العمود الداخلي القيمة NULL؟

قارن بين سلوك NOT EXISTS وسلوك NOT IN عند مصادفة قيمة NULL.

05

إذا كان للعميل رقم 101 اثنا عشر طلباً في جدول الطلبات، فكم مرة سيظهر هذا العميل في نتيجة الاستعلام SELECT u.user_id, u.full_name FROM users u WHERE EXISTS (...)؟

تذكّر ما إذا كان معامل EXISTS يكرر صفوف الجدول الخارجي عند تعدد التطابقات.