الدوال الرياضية (Numeric Functions)
مقدمة حول الدوال الرياضية في SQL
الدوال الرياضية في SQL هي مجموعة من الدوال المتخصصة التي تسمح لك بإجراء عمليات حسابية متقدمة على البيانات الرقمية. سواء كنت تريد تقريب الأرقام، حساب الجذور التربيعية، أو إجراء عمليات رياضية معقدة، فإن SQL توفر لك مجموعة شاملة من الدوال الرياضية.
في هذا الدرس، سنتعلم كيفية استخدام الدوال الرياضية الأكثر شيوعاً في SQL، مع أمثلة عملية توضح كيفية تطبيقها في سيناريوهات حقيقية.
لماذا الدوال الرياضية مهمة؟
- حساب الإحصائيات المالية (الأسعار، الضرائب، الخصومات)
- تقريب الأرقام لعرض أفضل
- إجراء حسابات علمية ورياضية
- معالجة البيانات الرقمية بدقة
- إنشاء تقارير مالية احترافية
دالة ROUND() - تقريب الأرقام
دالة ROUND() في SQL تُستخدم لتقريب رقم إلى عدد معين من المنازل العشرية. هذه الدالة مفيدة جداً عند التعامل مع الأسعار والقيم المالية.
الصيغة الأساسية:
ROUND(number, decimals)
حيث:
- number: الرقم المراد تقريبه
- decimals: عدد المنازل العشرية (اختياري، القيمة الافتراضية 0)
أمثلة عملية:
-- تقريب إلى أقرب عدد صحيح
SELECT ROUND(15.7) AS النتيجة;
-- النتيجة: 16
SELECT ROUND(15.4) AS النتيجة;
-- النتيجة: 15
-- تقريب إلى منزلتين عشريتين
SELECT ROUND(15.6789, 2) AS النتيجة;
-- النتيجة: 15.68
-- تقريب إلى منزلة عشرية واحدة
SELECT ROUND(15.6789, 1) AS النتيجة;
-- النتيجة: 15.7
-- تقريب للعشرات (استخدام قيمة سالبة)
SELECT ROUND(1567, -1) AS النتيجة;
-- النتيجة: 1570
SELECT ROUND(1567, -2) AS النتيجة;
-- النتيجة: 1600
مثال عملي - حساب الأسعار مع الضريبة:
CREATE TABLE products (
product_id INT PRIMARY KEY AUTO_INCREMENT,
product_name VARCHAR(100),
price DECIMAL(10, 2),
tax_rate DECIMAL(5, 2)
);
INSERT INTO products (product_name, price, tax_rate) VALUES
('لابتوب', 3500.00, 15.00),
('هاتف ذكي', 2200.00, 15.00),
('سماعات', 450.00, 15.00);
-- حساب السعر النهائي مع الضريبة (مقرب لمنزلتين)
SELECT
product_name,
price AS السعر_الأصلي,
tax_rate AS نسبة_الضريبة,
ROUND(price * (tax_rate / 100), 2) AS قيمة_الضريبة,
ROUND(price + (price * tax_rate / 100), 2) AS السعر_النهائي
FROM products;
| product_name | السعر_الأصلي | نسبة_الضريبة | قيمة_الضريبة | السعر_النهائي |
|---|---|---|---|---|
| لابتوب | 3500.00 | 15.00 | 525.00 | 4025.00 |
| هاتف ذكي | 2200.00 | 15.00 | 330.00 | 2530.00 |
| سماعات | 450.00 | 15.00 | 67.50 | 517.50 |
دالتا CEIL() و FLOOR() - التقريب للأعلى والأسفل
دالة CEIL() - التقريب للأعلى
دالة CEIL() أو CEILING() تُقرب الرقم إلى أقرب عدد صحيح أكبر منه أو يساويه.
-- أمثلة على CEIL
SELECT CEIL(15.1) AS النتيجة;
-- النتيجة: 16
SELECT CEIL(15.9) AS النتيجة;
-- النتيجة: 16
SELECT CEIL(15.0) AS النتيجة;
-- النتيجة: 15
SELECT CEIL(-15.1) AS النتيجة;
-- النتيجة: -15
دالة FLOOR() - التقريب للأسفل
دالة FLOOR() تُقرب الرقم إلى أقرب عدد صحيح أصغر منه أو يساويه.
-- أمثلة على FLOOR
SELECT FLOOR(15.1) AS النتيجة;
-- النتيجة: 15
SELECT FLOOR(15.9) AS النتيجة;
-- النتيجة: 15
SELECT FLOOR(15.0) AS النتيجة;
-- النتيجة: 15
SELECT FLOOR(-15.1) AS النتيجة;
-- النتيجة: -16
مثال عملي - حساب عدد الصفحات:
-- حساب عدد الصفحات المطلوبة لعرض المنتجات
-- (10 منتجات في كل صفحة)
SELECT
COUNT(*) AS إجمالي_المنتجات,
CEIL(COUNT(*) / 10) AS عدد_الصفحات_المطلوبة
FROM products;
-- مثال: إذا كان لديك 27 منتج
-- النتيجة: 3 صفحات (10 + 10 + 7)
- ROUND(15.5) = 16 (تقريب عادي)
- CEIL(15.1) = 16 (دائماً للأعلى)
- FLOOR(15.9) = 15 (دائماً للأسفل)
دالة ABS() - القيمة المطلقة
دالة ABS() في SQL تُرجع القيمة المطلقة للرقم (القيمة بدون الإشارة السالبة).
الصيغة الأساسية:
ABS(number)
أمثلة عملية:
-- أمثلة على ABS
SELECT ABS(15) AS النتيجة;
-- النتيجة: 15
SELECT ABS(-15) AS النتيجة;
-- النتيجة: 15
SELECT ABS(-15.75) AS النتيجة;
-- النتيجة: 15.75
SELECT ABS(0) AS النتيجة;
-- النتيجة: 0
مثال عملي - حساب الفرق المطلق بين قيمتين:
CREATE TABLE sales_targets (
employee_name VARCHAR(100),
target_amount DECIMAL(10, 2),
actual_amount DECIMAL(10, 2)
);
INSERT INTO sales_targets VALUES
('أحمد', 10000.00, 12000.00),
('فاطمة', 15000.00, 14000.00),
('خالد', 8000.00, 9500.00);
-- حساب الفرق والانحراف عن الهدف
SELECT
employee_name,
target_amount AS الهدف,
actual_amount AS المحقق,
actual_amount - target_amount AS الفرق,
ABS(actual_amount - target_amount) AS الفرق_المطلق,
ROUND((actual_amount - target_amount) / target_amount * 100, 2) AS نسبة_التحقيق
FROM sales_targets;
دالتا POWER() و SQRT() - الأس والجذر التربيعي
دالة POWER() - رفع رقم لأس معين
دالة POWER() تُستخدم لرفع رقم إلى أس معين.
POWER(base, exponent)
-- أمثلة على POWER
SELECT POWER(2, 3) AS النتيجة;
-- النتيجة: 8 (2³ = 2 × 2 × 2)
SELECT POWER(5, 2) AS النتيجة;
-- النتيجة: 25 (5² = 5 × 5)
SELECT POWER(10, 3) AS النتيجة;
-- النتيجة: 1000 (10³)
SELECT POWER(2, -1) AS النتيجة;
-- النتيجة: 0.5 (2⁻¹ = 1/2)
دالة SQRT() - الجذر التربيعي
دالة SQRT() تُرجع الجذر التربيعي لرقم.
-- أمثلة على SQRT
SELECT SQRT(16) AS النتيجة;
-- النتيجة: 4
SELECT SQRT(25) AS النتيجة;
-- النتيجة: 5
SELECT SQRT(2) AS النتيجة;
-- النتيجة: 1.4142135623730951
SELECT ROUND(SQRT(2), 2) AS النتيجة;
-- النتيجة: 1.41
مثال عملي - حساب المسافة بين نقطتين:
-- حساب المسافة الإقليدية بين نقطتين
-- المسافة = √[(x₂-x₁)² + (y₂-y₁)²]
SELECT
ROUND(
SQRT(
POWER(5 - 1, 2) + POWER(8 - 4, 2)
),
2
) AS المسافة;
-- النتيجة: 5.66
دالة MOD() - باقي القسمة
دالة MOD() في SQL تُرجع باقي قسمة رقم على رقم آخر.
الصيغة الأساسية:
MOD(dividend, divisor)
-- أو
dividend % divisor
أمثلة عملية:
-- أمثلة على MOD
SELECT MOD(10, 3) AS النتيجة;
-- النتيجة: 1 (10 ÷ 3 = 3 والباقي 1)
SELECT MOD(15, 4) AS النتيجة;
-- النتيجة: 3 (15 ÷ 4 = 3 والباقي 3)
SELECT MOD(20, 5) AS النتيجة;
-- النتيجة: 0 (20 ÷ 5 = 4 بدون باقي)
-- استخدام المعامل %
SELECT 17 % 5 AS النتيجة;
-- النتيجة: 2
مثال عملي - تحديد الأرقام الزوجية والفردية:
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
customer_name VARCHAR(100),
total_amount DECIMAL(10, 2)
);
INSERT INTO orders (customer_name, total_amount) VALUES
('أحمد', 150.00),
('فاطمة', 200.00),
('خالد', 175.00),
('سارة', 300.00),
('محمد', 125.00);
-- تصنيف الطلبات حسب رقم الطلب (زوجي/فردي)
SELECT
order_id,
customer_name,
total_amount,
CASE
WHEN MOD(order_id, 2) = 0 THEN 'زوجي'
ELSE 'فردي'
END AS نوع_الرقم
FROM orders;
مثال: توزيع البيانات على مجموعات:
-- توزيع الطلبات على 3 فرق عمل
SELECT
order_id,
customer_name,
MOD(order_id, 3) + 1 AS رقم_الفريق,
CASE MOD(order_id, 3)
WHEN 0 THEN 'الفريق الأول'
WHEN 1 THEN 'الفريق الثاني'
WHEN 2 THEN 'الفريق الثالث'
END AS اسم_الفريق
FROM orders;
دالة TRUNCATE() - قطع الأرقام العشرية
دالة TRUNCATE() تُستخدم لقطع الأرقام العشرية بدون تقريب (على عكس ROUND()).
الصيغة الأساسية:
TRUNCATE(number, decimals)
أمثلة عملية:
-- أمثلة على TRUNCATE
SELECT TRUNCATE(15.789, 2) AS النتيجة;
-- النتيجة: 15.78 (قطع بدون تقريب)
SELECT TRUNCATE(15.789, 1) AS النتيجة;
-- النتيجة: 15.7
SELECT TRUNCATE(15.789, 0) AS النتيجة;
-- النتيجة: 15
-- المقارنة بين TRUNCATE و ROUND
SELECT
15.789 AS الرقم_الأصلي,
TRUNCATE(15.789, 2) AS بعد_القطع,
ROUND(15.789, 2) AS بعد_التقريب;
| الرقم_الأصلي | بعد_القطع | بعد_التقريب |
|---|---|---|
| 15.789 | 15.78 | 15.79 |
دالة SIGN() - تحديد إشارة الرقم
دالة SIGN() تُرجع إشارة الرقم: 1 للموجب، -1 للسالب، 0 للصفر.
أمثلة عملية:
-- أمثلة على SIGN
SELECT SIGN(15) AS النتيجة;
-- النتيجة: 1
SELECT SIGN(-15) AS النتيجة;
-- النتيجة: -1
SELECT SIGN(0) AS النتيجة;
-- النتيجة: 0
-- مثال عملي: تصنيف الأرباح والخسائر
CREATE TABLE transactions (
transaction_id INT PRIMARY KEY AUTO_INCREMENT,
description VARCHAR(100),
amount DECIMAL(10, 2)
);
INSERT INTO transactions (description, amount) VALUES
('مبيعات', 5000.00),
('مصاريف', -2000.00),
('عمولات', 1500.00),
('غرامات', -500.00);
SELECT
description,
amount,
CASE SIGN(amount)
WHEN 1 THEN 'إيراد'
WHEN -1 THEN 'مصروف'
ELSE 'محايد'
END AS النوع
FROM transactions;
دوال PI() والدوال المثلثية
دالة PI() - قيمة باي (π)
دالة PI() تُرجع قيمة الثابت الرياضي π (باي) ≈ 3.141592653589793.
SELECT PI() AS قيمة_باي;
-- النتيجة: 3.141592653589793
-- حساب محيط دائرة (المحيط = 2πr)
SELECT ROUND(2 * PI() * 5, 2) AS محيط_دائرة_نصف_قطرها_5;
-- النتيجة: 31.42
-- حساب مساحة دائرة (المساحة = πr²)
SELECT ROUND(PI() * POWER(5, 2), 2) AS مساحة_دائرة_نصف_قطرها_5;
-- النتيجة: 78.54
الدوال المثلثية:
-- SIN() - جيب الزاوية
SELECT ROUND(SIN(PI()/2), 2) AS جيب_90_درجة;
-- النتيجة: 1.00
-- COS() - جيب التمام
SELECT ROUND(COS(0), 2) AS جيب_تمام_0_درجة;
-- النتيجة: 1.00
-- TAN() - ظل الزاوية
SELECT ROUND(TAN(PI()/4), 2) AS ظل_45_درجة;
-- النتيجة: 1.00
دالة RAND() - توليد أرقام عشوائية
دالة RAND() في SQL تُولد رقم عشوائي بين 0 و 1.
الصيغة الأساسية:
RAND()
-- أو مع seed للحصول على نفس النتائج
RAND(seed)
أمثلة عملية:
-- توليد رقم عشوائي بين 0 و 1
SELECT RAND() AS رقم_عشوائي;
-- النتيجة: 0.6324... (يتغير في كل مرة)
-- توليد رقم عشوائي بين 1 و 100
SELECT FLOOR(RAND() * 100) + 1 AS رقم_عشوائي_1_إلى_100;
-- توليد رقم عشوائي بين 10 و 50
SELECT FLOOR(RAND() * (50 - 10 + 1)) + 10 AS رقم_عشوائي_10_إلى_50;
-- اختيار صفوف عشوائية من جدول
SELECT * FROM products
ORDER BY RAND()
LIMIT 3;
مثال عملي - سحب عشوائي على جائزة:
-- اختيار فائز عشوائي من قائمة العملاء
SELECT
customer_name,
'فائز!' AS الحالة
FROM orders
ORDER BY RAND()
LIMIT 1;
أمثلة عملية متقدمة
مثال 1: نظام حساب الخصومات المتدرجة
-- حساب الخصومات بناءً على قيمة الطلب
SELECT
order_id,
customer_name,
total_amount AS المبلغ_الأصلي,
CASE
WHEN total_amount >= 1000 THEN 20
WHEN total_amount >= 500 THEN 15
WHEN total_amount >= 200 THEN 10
ELSE 5
END AS نسبة_الخصم,
ROUND(
total_amount * (
CASE
WHEN total_amount >= 1000 THEN 0.20
WHEN total_amount >= 500 THEN 0.15
WHEN total_amount >= 200 THEN 0.10
ELSE 0.05
END
),
2
) AS قيمة_الخصم,
ROUND(
total_amount - (
total_amount * (
CASE
WHEN total_amount >= 1000 THEN 0.20
WHEN total_amount >= 500 THEN 0.15
WHEN total_amount >= 200 THEN 0.10
ELSE 0.05
END
)
),
2
) AS المبلغ_النهائي
FROM orders;
مثال 2: حساب معدل النمو الشهري
CREATE TABLE monthly_sales (
month_name VARCHAR(20),
sales_amount DECIMAL(10, 2)
);
INSERT INTO monthly_sales VALUES
('يناير', 50000.00),
('فبراير', 55000.00),
('مارس', 52000.00),
('أبريل', 60000.00);
-- حساب معدل النمو
SELECT
month_name,
sales_amount AS المبيعات,
LAG(sales_amount) OVER (ORDER BY month_name) AS مبيعات_الشهر_السابق,
ROUND(
((sales_amount - LAG(sales_amount) OVER (ORDER BY month_name))
/ LAG(sales_amount) OVER (ORDER BY month_name)) * 100,
2
) AS معدل_النمو_بالنسبة_المئوية
FROM monthly_sales;
مثال 3: حساب المتوسط المتحرك
-- حساب المتوسط المتحرك لآخر 3 أشهر
SELECT
month_name,
sales_amount,
ROUND(
AVG(sales_amount) OVER (
ORDER BY month_name
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
),
2
) AS المتوسط_المتحرك_3_أشهر
FROM monthly_sales;
مثال 4: تصنيف المنتجات حسب السعر
-- تصنيف المنتجات إلى فئات سعرية
SELECT
product_name,
price,
CASE
WHEN price < 500 THEN 'اقتصادي'
WHEN price BETWEEN 500 AND 2000 THEN 'متوسط'
WHEN price BETWEEN 2001 AND 5000 THEN 'فاخر'
ELSE 'فاخر جداً'
END AS الفئة_السعرية,
ROUND((price / (SELECT MAX(price) FROM products)) * 100, 2) AS النسبة_من_أعلى_سعر
FROM products
ORDER BY price DESC;
أخطاء شائعة وكيفية تجنبها
1. الخلط بين ROUND و TRUNCATE
خطأ شائع: استخدام ROUND عندما تريد قطع الأرقام فقط
-- ROUND يقوم بالتقريب
SELECT ROUND(15.789, 2); -- النتيجة: 15.79
-- TRUNCATE يقوم بالقطع فقط
SELECT TRUNCATE(15.789, 2); -- النتيجة: 15.78
2. القسمة على صفر
خطأ شائع: عدم التحقق من القسمة على صفر
-- خطأ: قد يؤدي لخطأ أو NULL
SELECT total_amount / quantity FROM orders;
-- الحل الصحيح: التحقق من الصفر
SELECT
CASE
WHEN quantity = 0 THEN 0
ELSE total_amount / quantity
END AS السعر_للوحدة
FROM orders;
3. دقة الأرقام العشرية
خطأ شائع: عدم تحديد عدد المنازل العشرية المناسب
-- قد يعطي نتائج غير دقيقة
SELECT price * 1.15;
-- الأفضل: تحديد الدقة المطلوبة
SELECT ROUND(price * 1.15, 2) AS السعر_مع_الضريبة;
أفضل الممارسات
1. استخدم التقريب المناسب للسياق
- للأسعار: استخدم ROUND() مع منزلتين عشريتين
- للنسب المئوية: استخدم ROUND() مع منزلة أو منزلتين
- للإحصائيات: حدد الدقة حسب الحاجة
2. تجنب الحسابات المتكررة
-- بدلاً من تكرار الحساب
SELECT
price * 1.15,
price * 1.15 * 0.9
FROM products;
-- استخدم WITH أو متغيرات
WITH prices_with_tax AS (
SELECT
product_name,
price,
ROUND(price * 1.15, 2) AS price_with_tax
FROM products
)
SELECT
product_name,
price,
price_with_tax,
ROUND(price_with_tax * 0.9, 2) AS السعر_بعد_الخصم
FROM prices_with_tax;
3. استخدم أنواع البيانات المناسبة
- DECIMAL(10,2) للأسعار والمبالغ المالية
- FLOAT أو DOUBLE للحسابات العلمية
- INT للأعداد الصحيحة
4. وثق الحسابات المعقدة
-- أضف تعليقات توضيحية للحسابات المعقدة
SELECT
product_name,
price,
-- حساب السعر النهائي: السعر الأصلي + ضريبة 15% - خصم 10%
ROUND(
price * 1.15 * 0.9, -- (السعر × 1.15 للضريبة × 0.9 للخصم)
2
) AS السعر_النهائي
FROM products;
ملخص الدرس
في هذا الدرس، تعلمنا كيفية استخدام الدوال الرياضية في SQL:
- ROUND() - تقريب الأرقام إلى عدد معين من المنازل العشرية
- CEIL() و FLOOR() - التقريب للأعلى والأسفل
- ABS() - الحصول على القيمة المطلقة
- POWER() و SQRT() - الأس والجذر التربيعي
- MOD() - حساب باقي القسمة
- TRUNCATE() - قطع الأرقام العشرية بدون تقريب
- SIGN() - تحديد إشارة الرقم
- PI() والدوال المثلثية - للحسابات الهندسية
- RAND() - توليد أرقام عشوائية
هذه الدوال ضرورية لأي تطبيق يتعامل مع البيانات الرقمية، وستساعدك في إنشاء تقارير مالية دقيقة وإجراء حسابات معقدة بسهولة.
في الدرس القادم: سنتعلم عن الدوال الشرطية (Conditional Functions) في SQL، مثل CASE, IF(), IFNULL(), COALESCE()، وكيفية استخدامها لإنشاء منطق شرطي متقدم في استعلاماتك.
الخطوة التالية: دوال النصوص (String Functions)
أكمل رحلتك التعليمية وانتقل إلى الدرس التالي لتعلم دوال النصوص (String Functions) وتطوير مهاراتك في قواعد البيانات.
الانتقال إلى الدرس التالي