تخطَّ إلى المحتوى

الترتيب والصفحات في MySQL: ORDER BY و LIMIT

الدرس 5 من 12 · MySQL

في أي متجر إلكتروني، تجد قائمة «رتّب حسب»: السعر من الأقل، أو الأحدث، أو الأكثر مبيعاً. وتجد في أسفل الصفحة أرقام الصفحات: 1، 2، 3… في هذا الدرس ستتعلم كيف تبني الاثنين بـ MySQL: الترتيب بـ ORDER BY، وتقسيم النتائج إلى صفحات بـ LIMIT و OFFSET.

SELECT name, price FROM products ORDER BY price DESC;

الناتج:

name price
سماعة لاسلكية 450.50
حقيبة مدرسية 280.00
آلة حاسبة علمية 199.99
كتاب البرمجة للمبتدئين 120.00
قصص الأطفال 65.00
مجموعة أقلام 35.75
مسطرة 10.00
  • ORDER BY price: تصاعدي من الأرخص، وهو الافتراضي (ASC).
  • DESC: تنازلي من الأغلى.
  • خيار «الأحدث أولاً» في المتجر يصبح: ORDER BY added_on DESC.

وفي MySQL، القيم NULL تظهر أولاً في الترتيب التصاعدي وأخيراً في التنازلي.

تقسيم النتائج إلى صفحات

Section titled “تقسيم النتائج إلى صفحات”

متجر فيه 5000 منتج لا يعرضها كلها في صفحة واحدة! بل يعرض مثلاً 20 منتجاً في كل صفحة. في MySQL:

-- الصفحة الأولى
SELECT id, name FROM products ORDER BY id LIMIT 3 OFFSET 0;

الناتج:

id name
1 كتاب البرمجة للمبتدئين
2 سماعة لاسلكية
3 حقيبة مدرسية
-- الصفحة الثانية
SELECT id, name FROM products ORDER BY id LIMIT 3 OFFSET 3;

الناتج:

id name
4 آلة حاسبة علمية
5 قصص الأطفال
6 مجموعة أقلام
  • LIMIT 3: كم صفاً تريد (حجم الصفحة).
  • OFFSET 3: كم صفاً تتخطى أولاً.

القاعدة: لصفحة رقم n بحجم size، يكون OFFSET مساوياً لـ (n - 1) × size. فالصفحة الثالثة بحجم 20: LIMIT 20 OFFSET 40.

وفي MySQL صيغة مختصرة: LIMIT 3, 3 تعني «تخطَّ 3 ثم خذ 3»، أي نفس LIMIT 3 OFFSET 3. انتبه للترتيب في الصيغة المختصرة: الإزاحة أولاً ثم العدد.

تخيّل LIMIT و OFFSET مثل قراءة كتاب: OFFSET عدد الصفحات التي قرأتها وتتخطاها، و LIMIT عدد الصفحات التي ستقرؤها الآن.

الترتيب بعدة أعمدة وفخ ENUM

Section titled “الترتيب بعدة أعمدة وفخ ENUM”

لنرتب المنتجات حسب التصنيف، ثم السعر داخل كل تصنيف:

SELECT name, category, price FROM products ORDER BY category, price;

الناتج:

name category price
قصص الأطفال كتب 65.00
كتاب البرمجة للمبتدئين كتب 120.00
آلة حاسبة علمية إلكترونيات 199.99
سماعة لاسلكية إلكترونيات 450.50
مسطرة أدوات مدرسية 10.00
مجموعة أقلام أدوات مدرسية 35.75
حقيبة مدرسية أدوات مدرسية 280.00

لاحظ شيئاً غريباً: التصنيفات ليست مرتبة أبجدياً! جاءت «كتب» ثم «إلكترونيات» ثم «أدوات مدرسية». السبب: العمود category من نوع ENUM، و MySQL ترتب قيم ENUM حسب ترتيب تعريفها في الجدول: ENUM('كتب', 'إلكترونيات', 'أدوات مدرسية'). هذه من خصائص MySQL التي قد تفاجئك.

ماذا لو أردت عرض الإلكترونيات أولاً لأنها عليها عروض؟ الدالة FIELD تعطيك ترتيباً من اختيارك:

SELECT name, category FROM products
ORDER BY FIELD(category, 'إلكترونيات', 'كتب', 'أدوات مدرسية'), name;

الناتج:

name category
آلة حاسبة علمية إلكترونيات
سماعة لاسلكية إلكترونيات
قصص الأطفال كتب
كتاب البرمجة للمبتدئين كتب
حقيبة مدرسية أدوات مدرسية
مجموعة أقلام أدوات مدرسية
مسطرة أدوات مدرسية

FIELD(قيمة, أ, ب, ج) تُرجع موقع القيمة في القائمة: 1 أو 2 أو 3، فيتم الترتيب حسبه. ثم رتبنا بالاسم داخل كل تصنيف.

لقسم «منتج مقترح لك»، يمكن الترتيب عشوائياً: ORDER BY RAND() LIMIT 1. لكنها بطيئة مع الجداول الضخمة، لأن MySQL تعطي كل صف رقماً عشوائياً ثم ترتب الكل.

  1. اعرض المنتجات من الأحدث إضافة إلى الأقدم.
  2. اعرض أرخص 3 منتجات متوفرة في المخزن.
  3. قسّم المنتجات إلى صفحات من منتجين، واعرض الصفحة الثالثة.
  4. اعرض المنتجات بحيث تظهر «أدوات مدرسية» أولاً، ثم الباقي.
  5. تحدٍّ: اكتب الصيغة العامة لـ OFFSET لأي رقم صفحة وحجم صفحة.
  • LIMIT بدون ORDER BY: نتائج غير ثابتة بين الصفحات.
  • الخلط في LIMIT المختصرة: LIMIT 10, 5 تعني «تخطَّ 10 وخذ 5»، وليس العكس.
  • توقع ترتيب ENUM الأبجدي: يُرتَّب حسب ترتيب التعريف. استخدم FIELD أو حوّل لنص إذا احتجت ترتيباً آخر.

سؤال

أي استعلام يعرض الصفحة الثانية إذا كانت الصفحة 10 منتجات؟

سؤال

كيف ترتب MySQL عموداً من نوع ENUM؟

  • ORDER BY يبني خيارات «رتّب حسب»، و ASC افتراضي و DESC للتنازلي.
  • الصفحات بـ LIMIT size OFFSET (n - 1) × size، أو الصيغة المختصرة LIMIT offset, size.
  • الترقيم يحتاج ORDER BY ثابتاً ينتهي بعمود فريد.
  • عمود ENUM يُرتَّب حسب ترتيب تعريفه، و FIELD للترتيب المخصص.
  • ORDER BY RAND() للعشوائي، لكنه بطيء مع الجداول الضخمة.