في هذا الدرس 6تصفّح المواضيع
يختبر المعامل IN ما إذا كانت قيمة العمود تطابق أي عنصر داخل قائمة من القيم المفصولة بفواصل.
- اختصار الشيفرة ومنع الأخطاء: كتابة
WHERE status IN ('paid', 'shipped', 'delivered')أنظف وأقل عرضة للخطأ من تكرار جملORالمتتالية. - تحسين البحث الثنائي: عندما تكون عناصر القائمة قيماً ثابتة، يرتّبها محرك MySQL في الذاكرة وينفذ بحثاً ثنائياً سريعاً بدلاً من الفحص الخطي التقليدي.
احرص على توافق نوع بيانات القيم المكتوبة داخل القائمة مع نوع العمود ليستفيد محرك InnoDB من الفهارس بكفاءة.
التصفية ضمن القوائم والنطاقات الشاملة عبر IN و BETWEEN
-- Match orders in any of three active fulfillment states
SELECT order_id, customer_id, order_status, total_usd
FROM orders
WHERE order_status IN ('paid', 'packing', 'shipped');
تعمل صيغة NOT IN على عكس فحص القائمة؛ فلا تُرجع إلا الصفوف التي تختلف قيمة عمودها عن جميع العناصر المذكورة داخل القائمة.
- التمثيل المنطقي المكافئ: يترجم المحرك العبارة
col NOT IN (v1, v2, v3)إلى سلسلة شروط مرتبطة بـANDعلى الصورةcol <> v1 AND col <> v2 AND col <> v3. - تنظيف التقارير التشغيلية: تُعد أداة مثالية لاستبعاد الحسابات المؤرشفة أو التجريبية أو الملغاة دفعة واحدة.
تذكّر أن الصفوف التي يحمل عمودها القيمة NULL لن تظهر أيضاً لأن مقارنة NULL مع أي قيمة تُعيد NULL.
-- Exclude test and cancelled orders from revenue queries
SELECT order_id, customer_id, order_status, total_usd
FROM orders
WHERE order_status NOT IN ('cancelled', 'refunded', 'test');
يُعد وجود القيمة NULL داخل قائمة NOT IN (...) من أشهر الفخاخ المنطقية في لغة SQL على الإطلاق.
- لماذا ينجو المعامل IN من NULL: يتحول التعبير
x IN (10, 20, NULL)إلىx = 10 OR x = 20 OR x = NULL؛ فإذا كانت قيمةxهي10فإن النتيجة1 OR 0 OR NULLتساوي1وتظهر الصفوف المطابقة طبيعياً. - لماذا يُعيد NOT IN صفراً من الصفوف: يتحول التعبير
x NOT IN (10, 20, NULL)إلىx <> 10 AND x <> 20 AND x <> NULL؛ وبما أنx <> NULLيُعيد دائماًNULL، تصبح المعادلة1 AND 1 AND NULLوتساويNULLلكل صف في الجدول فيُستبعد الجميع!
لذلك احرص دائماً على خلو قوائم NOT IN تماماً من أي قيمة فارغة NULL.
-- Compare IN vs NOT IN when NULL is present in the list
SELECT (10 IN (10, 20, NULL)) AS in_with_null,
(30 NOT IN (10, 20, NULL)) AS not_in_with_null,
(30 NOT IN (10, 20)) AS safe_not_in;
يختبر المعامل BETWEEN min_val AND max_val وقوع قيمة العمود داخل نطاق متصل، مع شمول نقطتي البداية والنهاية معاً في النتيجة.
- التكافؤ المنطقي التام: العبارة
price BETWEEN 50 AND 100تكافئ تماماً كتابةprice >= 50 AND price <= 100. - أهمية ترتيب الحدين: يجب دائماً كتابة الحد الأصغر أولاً ثم الحد الأكبر؛ لأن كتابة
price BETWEEN 100 AND 50تعنيprice >= 100 AND price <= 50وهو شرط مستحيل يُعيد صفراً من الصفوف.
يمكنك استخدام NOT BETWEEN لاسترجاع القيم الواقعة خارج النطاق تماماً أي أصغر من الحد الأدنى أو أكبر من الحد الأعلى.
-- Products priced between 50 and 150 USD inclusive
SELECT product_id, title, unit_price
FROM products
WHERE unit_price BETWEEN 50.00 AND 150.00;
SELECT product_id, unit_price
FROM products
WHERE unit_price NOT BETWEEN 50.00 AND 150.00;
عند تصفية الأعمدة الزمنية، يجب التمييز بدقة بين أعمدة التاريخ فقط DATE وأعمدة التاريخ مع الوقت DATETIME أو TIMESTAMP.
- أعمدة
DATE: يعمل الشرطorder_date BETWEEN '2026-03-01' AND '2026-03-31'بشكل مثالي ويشمل جميع أيام شهر مارس بالكامل. - مشكلة منتصف الليل مع
DATETIME: عند تمرير تاريخ بدون وقت مثل'2026-03-31'لعمودDATETIME، يحوّله MySQL تلقائياً إلى'2026-03-31 00:00:00'فيستبعد جميع العمليات التي حدثت خلال ساعات يوم 31 مارس! لذا حدّد وقت نهاية اليوم صراحةً أو استخدم نطاقاً نصف مفتوح>= '2026-03-01' AND < '2026-04-01'.
يضمن النطاق نصف المفتوح شمول كافة أجزاء الثانية حتى في أعمدة الدقة العالية DATETIME(6).
-- Explicit full-day DATETIME bounds with BETWEEN
SELECT event_id, event_type, created_at
FROM audit_events
WHERE created_at BETWEEN '2026-03-01 00:00:00'
AND '2026-03-31 23:59:59';
يوضّح الجدول التالي مقارنة شاملة بين معاملات القوائم والنطاقات في MySQL 8 وما يكافئها منطقياً وسلوكها مع القيم الفارغة:
| المعامل | المكافئ المنطقي | سلوك الحدود والقوائم | تأثير وجود NULL |
|---|---|---|---|
x IN (a, b) | x = a OR x = b | يطابق القيم المنفصلة داخل القائمة | ينجح إذا طابقت x أي قيمة غير فارغة |
x NOT IN (a, b) | x <> a AND x <> b | يستبعد جميع القيم المذكورة | يُعيد 0 صفوف دائماً إذا وُجدت NULL بالقائمة |
x BETWEEN a AND b | x >= a AND x <= b | شامل للحدين الأدنى a والأعلى b | يُستبعد الصف إذا كانت x فارغة NULL |
x NOT BETWEEN a AND b | x < a OR x > b | خارج النطاق تماماً | يُستبعد الصف إذا كانت x فارغة NULL |
ملخص الدرس: أتقنت في هذا الدرس استخدام IN و NOT IN للتصفية عبر القوائم، وتجنّب فخ وجود NULL داخل NOT IN، وتصفية النطاقات الرقمية والزمنية الشاملة عبر BETWEEN.
الخطوة التالية والدرس القادم: ننتقل في الدرس القادم إلى البحث الجزئي داخل النصوص ومطابقة الأنماط عبر LIKE والتعابير النمطية REGEXP.
-- Combine IN list filtering with a BETWEEN price range
SELECT product_id, category, unit_price, stock_qty
FROM products
WHERE category IN ('Monitors', 'Keyboards', 'Audio')
AND unit_price BETWEEN 80.00 AND 400.00;
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
أتقنّا في هذا الدرس التصفية ضمن القوائم والنطاقات عبر IN و BETWEEN في MySQL في MySQL 8 مع أمثلة عملية.
الخطوة التالية والدرس القادم
أكمل التدريبات والاختبار التفاعلي أدناه قبل الانتقال إلى الدرس التالي في مسار MySQL.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 IN Operator معامل القائمة IN
- معامل في SQL يختبر تطابق قيمة العمود مع أي عنصر داخل قائمة محددة من القيم.
- للمراجعة
- 02 BETWEEN Operator معامل النطاق BETWEEN
- معامل يفحص وقوع القيمة ضمن نطاق متصل شامل للحدين الأدنى والأعلى.
- للمراجعة
- 03 NOT IN NULL Trap فخ NULL داخل NOT IN
- سلوك منطقي يؤدي فيه وجود قيمة NULL واحدة داخل قائمة NOT IN إلى إرجاع نتيجة فارغة تماماً.
- للمراجعة
- 04 Half-Open Date Range النطاق الزمني نصف المفتوح
- نمط تصفية زمني يستخدم >= بداية الفترة و < بداية الفترة التالية لشمول كامل ساعات وأجزاء اليوم الأخير.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 UTC UTC
- Coordinated Universal Time
- التوقيت العالمي المنسق الموصى به لتخزين ومقارنة النطاقات الزمنية
- للمراجعة
- 02 B-Tree B-Tree
- Balanced Tree Index
- بنية الفهرس المتوازن التي تسرّع فحص النطاقات في BETWEEN وقوائم IN
- للمراجعة
- 03 3VL 3VL
- Three-Valued Logic
- المنطق الثلاثي المفسّر لسبب إرجاع NOT IN مع NULL صفراً من الصفوف
- للمراجعة
- 04 ISO ISO
- International Organization for Standardization
- المنظمة الدولية للمعايير المعتمدة لصيغة التاريخ YYYY-MM-DD
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
اكتب استعلام SELECT على جدول invoices يعرض invoice_id و amount للفواتير التي تكون حالتها status ضمن القائمة ('pending', 'overdue').
-
اكتب استعلام SELECT على جدول employees يعرض emp_id و salary للموظفين الذين يتراوح راتبهم بين 3000 و 6000 شاملاً الحدين.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي8 أسئلة تنتظرك +
أي تعبير يكافئ منطقياً بنسبة 100% الشرط WHERE price BETWEEN 20 AND 50؟
المعامل BETWEEN شامل للحد الأدنى 20 والحد الأعلى 50 معاً.
كم صفاً يُعيد الاستعلام SELECT * FROM users WHERE role_id NOT IN (1, 2, NULL)؟
يتحول الشرط إلى سلسلة AND تتضمن role_id <> NULL وهي غير معروفة دائماً فلا ينجح أي صف.
ماذا يحدث عند كتابة الشرط WHERE price BETWEEN 200 AND 50 بوضع الرقم الأكبر أولاً؟
لا يبدّل MySQL ترتيب حدي BETWEEN بل يختبر price >= 200 AND price <= 50 فتكون النتيجة فارغة.
كيف يحسّن محرك MySQL أداء الشرط WHERE col IN (...) عندما تكون جميع عناصر القائمة قيماً ثابتة؟
يقوم MySQL بفرز قائمة الثوابت وتنفيذ بحث ثنائي سريع مما يمنح قوائم IN الثابتة أداءً عالياً.
لماذا قد يفوّت الشرط WHERE created_at BETWEEN '2026-05-01' AND '2026-05-31' بعض صفوف اليوم الأخير في عمود DATETIME؟
تحويل التاريخ المجرد إلى وقت يضبط الساعة على 00:00:00 مما يستبعد بقية ساعات اليوم الأخير.
ما التعبير المكافئ تماماً للشرط WHERE qty NOT BETWEEN 10 AND 20؟
بما أن BETWEEN يشمل 10 و 20 وما بينهما، فإن نفيه NOT BETWEEN يشمل ما هو أصغر تماماً من 10 أو أكبر تماماً من 20.
ما النتيجة التي يُعيدها الاستعلام SELECT (5 IN (5, 10, NULL)) في MySQL؟
التعبير 5 = 5 يُعيد 1، وفي المنطق الثلاثي فإن 1 OR 0 OR NULL يُعيد 1.
ما النتيجة التي يُعيدها الاستعلام SELECT (7 IN (5, 10, NULL)) في MySQL؟
يفشل التطابق مع 5 و 10 (0) وتبقى مقارنة 7 = NULL غير معروفة، فناتج 0 OR 0 OR NULL هو NULL.