في هذا الدرس 6تصفّح المواضيع
تمثّل القيمة NULL في قواعد البيانات غياب البيان أو عدم معرفته، وهي تختلف كلياً عن الرقم صفر 0 أو النص الفارغ ''. ولأن معامل التساوي العادي يفشل مع NULL، يوفر SQL معاملين مخصصين لفحصها.
- المعامل
IS NULL: يُعيد1عندما يكون العمود خالياً من أي قيمةNULL. - المعامل
IS NOT NULL: يُعيد1عندما يحتوي العمود على قيمة فعلية مسجلة (بما في ذلك الصفر أو السلسلة النصية الفارغة).
يدرج محرك InnoDB مفاتيح NULL داخل فهارس B-Tree، مما يسمح للشرط WHERE col IS NULL باستخدام الفهرس بسرعة عالية.
فحص القيم الفارغة بـ IS NULL والترتيب بـ ORDER BY وتقسيم الصفحات
-- Find unshipped orders vs completed shipments
SELECT order_id, customer_id, shipped_at
FROM orders
WHERE shipped_at IS NULL;
SELECT order_id, tracking_no, shipped_at
FROM orders
WHERE shipped_at IS NOT NULL;
بدون كتابة جملة ORDER BY صريحة، لا يضمن محرك قاعدة البيانات أي ترتيب ثابت للصفوف المسترجعة؛ فقد يتغير ترتيب ظهورها تبعاً للفهرس المستخدم أو تحديثات الصفحات.
- الترتيب التصاعدي
ASC(الافتراضي): يرتّب القيم من الأصغر إلى الأكبر رقمياً وأبجدياً ومن الأقدم إلى الأحدث زمنياً، ويُطبَّق تلقائياً عند عدم ذكر اتجاه الترتيب. - الترتيب التنازلي
DESC: يرتّب القيم من الأكبر إلى الأصغر ومن التاريخ الأحدث إلى الأقدم.
نظراً لأن جملة ORDER BY تُنفَّذ منطقياً بعد مرحلة SELECT، يمكنك استخدام الأسماء المستعارة المعرّفة بـ AS داخل ORDER BY مباشرة.
-- Sort products by net price alias from highest to lowest
SELECT product_id,
title,
(unit_price - discount_usd) AS net_price
FROM products
WHERE is_active = 1
ORDER BY net_price DESC;
يمكنك تمرير عدة أعمدة مفصولة بفواصل إلى جملة ORDER BY؛ حيث يرتّب MySQL الصفوف وفق العمود الأول أولاً، ولا يلجأ إلى العمود الثاني إلا لكسر التعادل بين الصفوف المتساوية في العمود الأول.
- استقلالية اتجاه كل عمود: يخص اتجاه
ASCأوDESCالعمود الذي يسبقه مباشرة فقط! فكتابةORDER BY dept_id, salary DESCتعني ترتيب رقم القسم تصاعدياًASCوترتيب الراتب تنازلياًDESCداخل كل قسم. - كسر التعادل بالمفتاح الأساسي: أضف دائماً عموداً فريداً مثل المفتاح الأساسي
id ASCكآخر عمود في الترتيب لضمان ثبات مواقع الصفوف المتساوية عند تقسيم الصفحات.
يدعم MySQL 8 الفهارس التنازلية المختلطة Descending Indexes لتسريع الترتيب المتعدد دون الحاجة لعملية فرز إضافية filesort.
-- Sort by department ascending, then highest salary, then id
SELECT emp_id, full_name, dept_id, salary
FROM employees
WHERE is_active = 1
ORDER BY dept_id ASC, salary DESC, emp_id ASC;
عند ترتيب عمود يقبل القيم الفارغة في MySQL، يعامل المحرك القيمة NULL على أنها أصغر من أي قيمة غير فارغة أخرى عند الفرز.
- مع الترتيب التصاعدي
ASC: تظهر الصفوف التي تحتوي علىNULLفي بداية النتائج أولاً. - مع الترتيب التنازلي
DESC: تظهر الصفوف التي تحتوي علىNULLفي نهاية النتائج أخيراً. - دفع قيم NULL للنهاية مع الترتيب التصاعدي: نظراً لعدم وجود كلمة
NULLS LASTفي MySQL، نستخدم الحيلة المنطقية الأنيقةORDER BY (col IS NULL) ASC, col ASC؛ حيث يُعيد التعبيرcol IS NULLالقيمة0للصفوف المكتملة فتظهر أولاً، ويُعيد1للصفوف الفارغة فتُدفع إلى آخر القائمة!
تعمل هذه الطريقة القياسية بكفاءة مع الأرقام والنصوص والتواريخ على حد سواء.
-- Push NULL delivery dates to the bottom while sorting ASC
SELECT task_id, title, due_date
FROM project_tasks
ORDER BY (due_date IS NULL) ASC,
due_date ASC,
task_id ASC;
تُنفَّذ جملة LIMIT في المرحلة الأخيرة من الاستعلام بعد اكتمال الفرز بـ ORDER BY لتقييد عدد الصفوف المرسلة إلى التطبيق.
- جلب أعلى N سجلات
LIMIT count: كتابةLIMIT 5تكتفي بإرجاع أول 5 صفوف فقط. - تقسيم الصفحات
LIMIT count OFFSET skip: لعرض الصفحة رقمPبحجمNصفاً في كل صفحة، نحسب الإزاحة بالمعادلةskip = (P - 1) * N؛ فعند عرض 10 عناصر بالصفحة، تستخدم الصفحة الأولىLIMIT 10 OFFSET 0، والثانيةLIMIT 10 OFFSET 10، والثالثةLIMIT 10 OFFSET 20.
استخدم دائماً الصيغة الصريحة LIMIT count OFFSET skip بدلاً من صيغة الفاصلة القديمة LIMIT skip, count لتفادي عكس الرقمين بالخطأ.
-- Page 3 of active products (10 per page -> skip first 20)
SELECT product_id, title, unit_price
FROM products
WHERE is_active = 1
ORDER BY unit_price DESC, product_id ASC
LIMIT 10 OFFSET 20;
يلخّص الجدول التالي الأنماط القياسية لفحص القيم الفارغة وترتيب النتائج وتقسيم الصفحات في MySQL 8:
| النمط / الجملة | مثال الصياغة | السلوك التنفيذي |
|---|---|---|
| فحص غياب القيمة | WHERE col IS NULL | يطابق الصفوف التي تكون فيها قيمة العمود فارغة |
| فحص وجود القيمة | WHERE col IS NOT NULL | يطابق الصفوف التي تحتوي على قيمة مسجلة |
| الترتيب المتعدد | ORDER BY dept ASC, pay DESC | يرتّب بالقسم تصاعدياً ويكسر التعادل بالراتب تنازلياً |
| وضع NULL أخيراً | ORDER BY (col IS NULL), col ASC | يعرض القيم الفعلية أولاً ثم يدفع NULL للنهاية |
| تقسيم الصفحات القياسي | LIMIT 20 OFFSET 40 | يتخطى 40 صفاً ويعرض 20 صفاً (الصفحة الثالثة) |
| التقسيم بالمؤشر Keyset | WHERE id > 500 ORDER BY id LIMIT 20 | يقفز عبر الفهرس مباشرة دون مسح الصفوف المتخطاة |
ملخص الدرس: أتقنت في هذا الدرس فحص القيم الفارغة عبر IS NULL و IS NOT NULL، والترتيب المفرد والمتعدد بجملة ORDER BY، والتحكم في موقع ظهور NULL، وتقسيم الصفحات عبر LIMIT و OFFSET.
الخطوة التالية والدرس القادم: نبدأ في الدرس القادم وحدة تجميع البيانات Data Aggregation بتعلّم الدوال التجميعية الخمس COUNT و SUM و AVG و MIN و MAX.
-- Complete filter, NULL-last sort, and page-1 query
SELECT order_id, customer_id, shipped_at, total_usd
FROM orders
WHERE order_status = 'paid'
ORDER BY (shipped_at IS NULL) ASC, shipped_at ASC, order_id ASC
LIMIT 15 OFFSET 0;
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
أتقنّا في هذا الدرس فحص القيم الفارغة والترتيب بـ ORDER BY وتقسيم الصفحات بـ LIMIT في MySQL 8 مع أمثلة عملية.
الخطوة التالية والدرس القادم
أكمل التدريبات والاختبار التفاعلي أدناه قبل الانتقال إلى الدرس التالي في مسار MySQL.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 IS NULL / IS NOT NULL فحص القيمة الفارغة IS NULL
- معاملان مخصصان في SQL لاختبار ما إذا كان العمود فارغاً NULL أو يحتوي على قيمة فعلية.
- للمراجعة
- 02 ORDER BY Clause جملة الترتيب ORDER BY
- جملة في SQL تُنفَّذ بعد SELECT لفرز الصفوف المسترجعة تصاعدياً ASC أو تنازلياً DESC.
- للمراجعة
- 03 LIMIT and OFFSET تحديد النتائج والإزاحة LIMIT / OFFSET
- جملتان في نهاية الاستعلام لتحديد أقصى عدد للصفوف المسترجعة LIMIT بعد تخطي عدد محدد من الصفوف OFFSET.
- للمراجعة
- 04 Filesort فرز الذاكرة أو القرص (Filesort)
- عملية الفرز الداخلية التي ينفذها MySQL عندما لا يتوفر فهرس مرتّب يطابق جملة ORDER BY مباشرة.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 ASC ASC
- Ascending Order
- الترتيب التصاعدي من الأصغر إلى الأكبر (وهو الاتجاه الافتراضي في ORDER BY)
- للمراجعة
- 02 DESC DESC
- Descending Order
- الترتيب التنازلي من الأكبر إلى الأصغر أو من الأحدث إلى الأقدم
- للمراجعة
- 03 UI UI
- User Interface
- واجهة المستخدم التي تعرض جداول البيانات المقسمة إلى صفحات عبر LIMIT و OFFSET
- للمراجعة
- 04 API API
- Application Programming Interface
- واجهة برمجة التطبيقات التي تعتمد على الترتيب الحاسم والتقسيم الصفحي للبيانات
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
اكتب استعلام SELECT على جدول users يعرض user_id و username للمستخدمين الذين تكون قيمة phone_number لديهم فارغة NULL.
-
اكتب استعلام SELECT على جدول orders يعرض order_id و created_at مرتبةً تنازلياً حسب created_at DESC ثم order_id DESC، مع إرجاع 10 صفوف للصفحة الثانية (تخطي أول 10 صفوف).
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي8 أسئلة تنتظرك +
أي شرط داخل WHERE يطابق بشكل صحيح الصفوف التي يكون فيها العمود deleted_at فارغاً NULL؟
المقارنة بعلامة = مع NULL تُعيد دائماً UNKNOWN؛ لذا يجب استخدام IS NULL.
ما اتجاه الترتيب الافتراضي في جملة ORDER BY عند عدم كتابة ASC أو DESC؟
يطبق محرك MySQL الترتيب التصاعدي ASC افتراضياً على كل عمود في ORDER BY ما لم يُذكر DESC صراحةً بعده.
كيف يرتّب محرك MySQL الاستعلام عند كتابة ORDER BY category, price DESC؟
تنطبق كلمة DESC على العمود الذي يسبقها مباشرة (price)، بينما يأخذ العمود الأول category الاتجاه الافتراضي ASC.
أين تظهر الصفوف التي تحتوي على NULL عند الفرز التصاعدي ORDER BY score ASC في MySQL؟
يعامل MySQL القيمة NULL كأصغر قيمة عند الفرز فتظهر أولاً في الترتيب التصاعدي ASC وأخيراً في التنازلي DESC.
أي صياغة لـ ORDER BY تعرض القيم غير الفارغة مرتبةً تصاعدياً أولاً وتدفع قيم NULL إلى نهاية النتائج؟
يُعيد التعبير (score IS NULL) القيمة 0 للصفوف الممتلئة و 1 للصفوف الفارغة فتظهر القيم الممتلئة أولاً.
عند عرض 25 صفاً في كل صفحة، أي جملة تسترجع بيانات الصفحة الرابعة (Page 4)؟
تُحسب الإزاحة بالمعادلة (4 - 1) * 25 = 75، لذا نتخطى أول 75 صفاً ونجلب 25 صفاً.
هل يمكن استخدام الاسم المستعار المعرّف في جملة SELECT داخل جملة ORDER BY؟
بما أن مرحلة الفرز ORDER BY تأتي بعد استخراج أعمدة SELECT، فإن الأسماء المستعارة تكون متاحة للاستخدام المباشر.
ماذا تعني صيغة الفاصلة القديمة LIMIT 20, 10 في MySQL؟
في صيغة الفاصلة القديمة يمثّل الرقم الأول الإزاحة (20) والثاني عدد الصفوف (10)، ولذلك يُفضّل كتابة LIMIT 10 OFFSET 20 لوضوحها.