Menu
flag Ar iconالعربيةdown icon

دوال الأرقام في SQLite: ROUND وABS وCEIL وFLOOR

كيف تجري العمليات الحسابية في SQLite عبر ROUND وABS وCEIL وFLOOR وMOD وPOWER وSQRT وRANDOM، مع شرح فخ القسمة الصحيحة الذي يقع فيه الجميع.

تحتوي هذه الصفحة على محررات قابلة للتشغيل — حرّر، شغّل، وشاهد النتيجة فوراً.

دوال الأرقام في SQLite أكثر مما تتوقع

رغم أن SQLite معروفة بأنها بسيطة وخفيفة، إلا أنها تأتي مزوّدة بمجموعة كاملة من الدوال الرياضية: التقريب، القيمة المطلقة، السقف والأرضية، الأسس، الجذور، اللوغاريتمات، الدوال المثلثية، والأرقام العشوائية. أُضيفت معظم الدوال الرياضية في الإصدار SQLite 3.35 الصادر عام 2021، لذا فإن أي نسخة حديثة نسبيًا — سواء تلك المرفقة مع Python أو Node.js أو واجهة الأوامر الرسمية — تدعمها جاهزة للاستخدام.

إليك لمحة سريعة قبل أن نتعمق في التفاصيل:

ست دوال، وصف نتائج واحد. بقية هذه الصفحة تشرح كل عائلة من هذه الدوال ولماذا نستخدمها، مع التنبيه على بعض النقاط التي يجدر الانتباه لها.

دالة ROUND: الأكثر استخداماً في تقريب الأرقام في SQLite

تقوم ROUND(value, digits) بتقريب الرقم إلى عدد محدد من الخانات العشرية. المُعامل الثاني اختياري؛ إذا لم تُمرّره، فسيتم التقريب إلى أقرب عدد صحيح، لكن النتيجة تظل قيمة عشرية (floating-point):

أمور يجب أن تنتبه لها:

  • ROUND(3.14159) تُرجع 3.0، وليس 3. إذا كنت تريد عدداً صحيحاً، استخدم CAST(ROUND(x) AS INTEGER)، أو استعمل CAST(x AS INTEGER) مباشرةً للاقتطاع (truncation).
  • SQLite يعتمد طريقة "التقريب بعيداً عن الصفر" (round half away from zero) — أي أن 2.5 تصبح 3، و-2.5 تصبح -3. بعض قواعد البيانات الأخرى تستخدم تقريب المصرفيين (banker's rounding) الذي يقرّب إلى الزوجي الأقرب، أما SQLite فلا يفعل ذلك.
  • الوسيط digits يقبل قيماً سالبة: فمثلاً ROUND(1234.5, -2) يقرّب لأقرب مئة، فتكون النتيجة 1200.

عملياً، أكثر استخدام ستراه في الكود هو ROUND(price, 2) لعرض المبالغ المالية.

الفرق بين ROUND وCAST في SQLite

كثير من المطورين يلجأون إلى CAST(x AS INTEGER) ظنّاً منهم أنها تقوم بالتقريب، فيقعون في فخ غير متوقع:

CAST يقتطع باتجاه الصفر — يعني ببساطة يرمي الجزء العشري ويتجاهله. أمّا ROUND فيقرّب إلى أقرب عدد صحيح. خُذ مثلًا الرقم 2.9: الفرق بينهما يصل إلى وحدة كاملة. اختر الدالة التي يناسبك سلوكها فعلًا.

دالتا ABS وSIGN وإشارة الرقم

تُعيد ABS(x) القيمة المطلقة للرقم. بينما تُعيد SIGN(x) إحدى القيم -1 أو 0 أو 1 بحسب إشارة الرقم:

ABS هي الدالة الأكثر استخدامًا — مفيدة جدًا لاستعلامات من نوع "ما الفرق بين هاتين القيمتين؟". أما SIGN فاستخدامها أقل شيوعًا، لكنها تنفع حين تريد تصنيف الصفوف حسب الاتجاه (مدين مقابل دائن، ربح مقابل خسارة) دون الحاجة إلى CASE صريح.

الدوال CEIL وFLOOR وTRUNC في SQLite

تعطيك هذه الدوال قيمًا قريبة من العدد الصحيح دون تقريب إلى الأقرب. CEIL تقرّب دائمًا للأعلى، وFLOOR تقرّب دائمًا للأسفل، أما TRUNC فتقتطع الجزء العشري باتجاه الصفر:

انتبه للحالات السالبة. FLOOR(-2.9) يعطيك -3 (أبعد عن الصفر)، بينما TRUNC(-2.9) يعطيك -2 (أقرب إلى الصفر). عند التعامل مع الأرقام السالبة، FLOOR و TRUNC لا يتفقان، واختيار الخاطئ منهما هو سبب كلاسيكي لخطأ الفرق بواحد.

CEILING هو اسم بديل لـ CEIL. استخدم الصيغة التي تريحك في القراءة.

القسمة الصحيحة في SQLite هي الفخ الحقيقي

هذه ليست دالة، بل المعامل /، لكنها توقع المبتدئين أكثر من أي دالة رياضية فعلية:

عندما يكون الطرفان عددين صحيحين، فإن SQLite ينفّذ قسمة صحيحة ويقتطع الكسر. وبمجرد أن يصبح أحد الطرفين من نوع REAL، يتحول التعبير كله إلى عدد عشري. الحل بسيط: تأكّد أن أحد المعاملات على الأقل عدد عشري — إما بكتابة 2.0 بدلاً من 2، أو باستخدام التحويل الصريح عبر CAST.

وتظهر هذه المشكلة بوضوح مع أعمدة الجداول: العملية total_cents / 100 ترجع عددًا صحيحًا، بينما total_cents / 100.0 ترجع قيمة الدولار التي كنت تريدها فعلاً.

دالة MOD ومعامل % لحساب باقي القسمة في SQLite

تُرجع MOD(x, y) باقي قسمة x على y، ومعامل % يقوم بالدور نفسه تمامًا:

MOD(17, 5) و 17 % 5 كلاهما يُرجع 2. لكن انتبه: عملية باقي القسمة على صفر تُرجع NULL في SQLite ولا تُطلق أي خطأ، وهذا سلوك غير مألوف مقارنةً بمعظم اللغات الأخرى. إذا كان هذا مهمًا في حالتك، تحقّق من المقسوم عليه أولًا أو غلّف الاستدعاء بـ CASE WHEN y = 0 THEN ... END.

شكل الدالة وشكل المعامل متكافئان تمامًا، لكن الأغلب يستخدم % لأنه أقصر.

الأُسس والجذور: POWER وSQRT وEXP وLOG

للتعامل مع الأُسس والجذور:

بعض الملاحظات التي بتلخبط الناس:

  • POW هي مجرد اسم بديل لـ POWER.
  • الدالة LOG(x) في SQLite تحسب اللوغاريتم بالأساس 10، أما LN(x) فهي اللوغاريتم الطبيعي. ولو مرّرت وسيطين LOG(b, x) فالحساب يكون باللوغاريتم بالأساس b. (هذا يختلف عن كثير من لغات البرمجة التي تعتبر log لوغاريتمًا طبيعيًا، لكن في النهاية ساد العُرف المتبع في SQL.)
  • SQRT لرقم سالب يرجّع NULL بدل ما يطلع خطأ.
  • POWER(0, 0) يرجّع 1 حسب الاتفاق الرياضي الشائع.

هذي الدوال مفيدة في حسابات الفائدة المركبة، والتحويل إلى الديسيبل، وحساب المسافات، وأي مكان فيه رياضيات هندسية أو أسّية.

دالتا RANDOM و RANDOMBLOB

الدالة RANDOM() ترجّع عددًا صحيحًا بإشارة بحجم 64 بت، وقيمته ممكن تكون في أي مكان ضمن المدى الكامل:

للحصول على رقم ضمن نطاق محدد، استخدم ABS (لأن RANDOM() يُرجع قيمة بإشارة موجبة أو سالبة) مع عامل %. وللحصول على رقم حقيقي بين 0 و1، اقسم الناتج على أكبر عدد صحيح بحجم 64-bit. لا تتوفر في SQLite دالة RAND() جاهزة تُرجع قيمة بين 0 و1، فعليك تركيبها بنفسك.

أما RANDOMBLOB(n) فتُرجع n بايت من البيانات العشوائية، وهي مفيدة لتوليد رموز الجلسات (session tokens) أو بيانات اختبار. يمكنك دمجها مع HEX() للحصول على نص قابل للطباعة:

كل استدعاء يُنتج قيمة جديدة. لا تتوقع أن تُرجع RANDOM() نفس الرقم مرتين في الصف ذاته، حتى داخل التعبير الواحد، فكل استدعاء مستقل عن الآخر.

مثال تطبيقي شامل

مثال صغير مطبَّق: حساب المسافات وتقريب الأسعار في جدول منتجات.

النقطة المهمة هنا هي price_cents / 100.0 — وجود .0 هو ما يحوّل عملية القسمة إلى قسمة عشرية، ثم تأتي ROUND لتنسيق الناتج برقمين بعد الفاصلة. بدون هذا، ستعطيك 1299 / 100 الناتج 12 فقط، وليس 12.99.

ما القادم: التاريخ والوقت

دوال الأرقام في SQLite تتكفّل بالعمليات الحسابية، أمّا التاريخ والوقت فلهما عُدّتهما الخاصة. يخزّن SQLite قيم التاريخ والوقت إمّا كنص أو كعدد عشري أو كعدد صحيح، ويوفّر مجموعة صغيرة لكن قويّة من الدوال للتعامل معها: تحليلها، تنسيقها، وإجراء العمليات الحسابية عليها. وهذا تماماً ما سنتناوله في الجزء التالي.

الأسئلة الشائعة

كيف أقرّب الرقم لأقرب خانتين عشريتين في SQLite؟

استخدم ROUND(value, 2). الوسيط الثاني هو عدد الخانات العشرية التي تريد الإبقاء عليها، فمثلاً ROUND(3.14159, 2) يُرجع 3.14. أما إذا استخدمت ROUND(x) بوسيط واحد فقط، فهي تقرّب لأقرب عدد صحيح لكنها تعيد قيمة من نوع عشري (floating-point) — وهذا ما يفاجئ كثيرين.

هل تدعم SQLite دالتي CEIL وFLOOR؟

نعم، منذ إصدار SQLite 3.35 (عام 2021) أصبحت الدوال الرياضية مدمجة افتراضياً: CEIL(x) وFLOOR(x) وSQRT(x) وPOWER(x, y) وLOG(x) وEXP(x) وغيرها. في الإصدارات الأقدم لن تجدها متاحة ما لم تُحمَّل إضافة math، لكن معظم النسخ الحديثة (Python وNode والمتصفحات) تأتي بها مفعّلة.

لماذا تُرجع العملية 5 / 2 الناتج 2 في SQLite؟

لأن كلا الطرفين عددان صحيحان، فتُجري SQLite قسمة صحيحة وتقتطع الجزء العشري. الحل أن تحوّل أحد الطرفين إلى REAL، مثل 5 / 2.0 أو CAST(5 AS REAL) / 2، لتحصل على 2.5. هذه ليست خاصية تتعلق بدوال الأرقام، بل سلوك العامل / نفسه عندما يكون طرفاه أعداداً صحيحة.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن