في هذا الدرس 6تصفّح المواضيع
من أشهر الأنماط التحليلية للاستعلام الفرعي المترابط مقارنة كل صف بمتوسط أو أعلى قيمة داخل مجموعته الخاصة؛ مثل استخراج الموظفين الذين يتجاوز راتبهم متوسط رواتب قسمهم، أو المنتجات الأعلى سعراً من متوسط فئتها:
- اسمان مستعاران لنفس الجدول: امنح الجدول الخارجي الاسم المستعار
p1والجدول الداخلي الاسم المستعارp2. - شرط ربط المجموعة: اربط دالة التجميع الداخلية بفئة الصف الخارجي الحالي عبر الشرط
WHERE p2.category_id = p1.category_id.
-- 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داخل الاستعلام الفرعي.
-- 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 (subquery) على تصفية الجدول الخارجي للإبقاء فقط على السجلات التي لا تملك أي صف مطابق في الاستعلام الداخلي المترابط:
- تعبير مباشر عن عدم الارتباط: يعبّر
NOT EXISTSبوضوح عن قواعد العمل مثل «العملاء الذين لم يسجلوا أي طلب في 2026» أو «المنتجات التي لم تُسترجع أبداً». - دعم الشروط المركبة: يمكنك إضافة عدة شروط تصفية داخل جملة
WHEREالداخلية بجانب شرط الترابط الرئيسي.
-- Find active products that have never been ordered
SELECT
p.product_id,
p.sku_code,
p.product_title
FROM products AS p
WHERE p.is_active = 1
AND NOT EXISTS (
SELECT 1
FROM order_items AS oi
WHERE oi.product_id = p.product_id
);
عند البحث عن السجلات غير المرتبطة، يُعد الاختيار بين 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في الجدول الداخلي.
-- 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
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 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
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 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.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
نفّذ أمثلة SQL المشروحة في قسم الاستعلام المستقل مقابل المترابط داخل قاعدة بياناتك المحلية وتحقق من مجموعة النتائج.
-
بدّل بين الحالات التفاعلية في قسم مقارنة الصف بمتوسط مجموعته وقارن كيف ينفّذ محرك MySQL 8 كل استعلام.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي5 أسئلة تنتظرك +
ما الذي يميز الاستعلام الفرعي المترابط عن الاستعلام الفرعي المستقل في MySQL؟
ركّز على علاقة الاستعلام الداخلي بأعمدة الاستعلام الخارجي.
في الشرط WHERE p1.unit_price > (SELECT AVG(p2.unit_price) FROM products AS p2 WHERE p2.category_id = p1.category_id)، ماذا يرجع الاستعلام؟
حلّل معنى ربط رقم الفئة الداخلي برقم فئة المنتج الخارجي.
عند تنفيذ WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.user_id)، يتوقف MySQL عن فحص بقية طلبات ذلك العميل فور العثور على أول طلب مطابق.
تحقق من خاصية التوقف المبكر السريع في معامل EXISTS.
لماذا يُفضّل استخدام WHERE NOT EXISTS (...) بشدة على WHERE user_id NOT IN (SELECT user_id FROM orders) عندما يقبل العمود الداخلي القيمة NULL؟
قارن بين سلوك NOT EXISTS وسلوك NOT IN عند مصادفة قيمة NULL.
إذا كان للعميل رقم 101 اثنا عشر طلباً في جدول الطلبات، فكم مرة سيظهر هذا العميل في نتيجة الاستعلام SELECT u.user_id, u.full_name FROM users u WHERE EXISTS (...)؟
تذكّر ما إذا كان معامل EXISTS يكرر صفوف الجدول الخارجي عند تعدد التطابقات.