گرد کردن اعداد در SQL Server: راهنمای کامل توابع ROUND, CEILING و FLOOR با Bankers Rounding
در SQL Server، گرد کردن اعداد یک عملیات رایج است که با استفاده از توابع مختلفی انجام میشود. این راهنما به بررسی توابع `ROUND`, `CEILING`, `FLOOR` و نحوه عملکرد قانون Banker’s Rounding میپردازد که در سناریوهای مختلف گرد کردن اعداد کاربرد دارند.
**تابع ROUND در SQL Server**
تابع `ROUND` در SQL Server برای گرد کردن یک مقدار عددی به یک طول یا دقت مشخص استفاده میشود. این تابع میتواند اعداد را به بالا یا پایین بر اساس قوانین خاصی گرد کند.
سینتکس تابع `ROUND` به صورت زیر است:
ROUND (numeric_expression, length [,function])
در این سینتکس:
* `numeric_expression`: یک عبارت با دقت عددی دقیق یا تقریبی است که باید گرد شود.
* `length`: عدد صحیح است که دقت گرد کردن را مشخص میکند. اگر یک عدد مثبت باشد، عدد به تعداد `length` رقم اعشار گرد میشود. اگر عدد منفی باشد، قسمت صحیح عدد گرد میشود.
* `function`: یک پارامتر اختیاری است که اگر مقدار غیرصفر داشته باشد، `numeric_expression` را قطع میکند (truncate) و گرد نمیکند.
در اینجا چند مثال از نحوه عملکرد تابع `ROUND` آورده شده است:
SELECT ROUND(123.456, 2) AS RoundValue;
-- نتیجه: 123.460
SELECT ROUND(123.454, 2) AS RoundValue;
-- نتیجه: 123.450
SELECT ROUND(123.456, 0) AS RoundValue;
-- نتیجه: 123.000
SELECT ROUND(123.456, -1) AS RoundValue;
-- نتیجه: 120.000
SELECT ROUND(123.456, -2) AS RoundValue;
-- نتیجه: 100.000
**قانون Banker’s Rounding**
یکی از نکات مهم در مورد تابع `ROUND` در SQL Server، استفاده از قانون Banker’s Rounding برای اعدادی است که دقیقاً در نقطه میانی بین دو عدد قرار دارند (مانند 2.5، 3.5، 4.5 و غیره). طبق این قانون، اعداد 0.5 به نزدیکترین عدد زوج گرد میشوند. این رفتار میتواند برای دقتهای مالی و آماری مهم باشد.
در اینجا چند مثال برای درک بهتر قانون Banker’s Rounding آورده شده است:
SELECT ROUND(2.5, 0) AS RoundValue;
-- 2.5 به 2 گرد میشود (نزدیکترین عدد زوج).
SELECT ROUND(3.5, 0) AS RoundValue;
-- 3.5 به 4 گرد میشود (نزدیکترین عدد زوج).
SELECT ROUND(4.5, 0) AS RoundValue;
-- 4.5 به 4 گرد میشود (نزدیکترین عدد زوج).
SELECT ROUND(5.5, 0) AS RoundValue;
-- 5.5 به 6 گرد میشود (نزدیکترین عدد زوج).
**تابع CEILING در SQL Server**
تابع `CEILING` در SQL Server کوچکترین عدد صحیح را که بزرگتر یا مساوی با عبارت عددی مشخص شده است، برمیگرداند. به عبارت دیگر، این تابع همیشه یک عدد را به سمت بالا گرد میکند.
سینتکس تابع `CEILING` به صورت زیر است:
CEILING (numeric_expression)
در اینجا چند مثال از نحوه عملکرد تابع `CEILING` آورده شده است:
SELECT CEILING(123.456) AS CeilingValue;
-- نتیجه: 124
SELECT CEILING(123.000) AS CeilingValue;
-- نتیجه: 123
SELECT CEILING(123.999) AS CeilingValue;
-- نتیجه: 124
SELECT CEILING(-123.456) AS CeilingValue;
-- نتیجه: -123
**تابع FLOOR در SQL Server**
تابع `FLOOR` در SQL Server بزرگترین عدد صحیح را که کوچکتر یا مساوی با عبارت عددی مشخص شده است، برمیگرداند. به عبارت دیگر، این تابع همیشه یک عدد را به سمت پایین گرد میکند.
سینتکس تابع `FLOOR` به صورت زیر است:
FLOOR (numeric_expression)
در اینجا چند مثال از نحوه عملکرد تابع `FLOOR` آورده شده است:
SELECT FLOOR(123.456) AS FloorValue;
-- نتیجه: 123
SELECT FLOOR(123.000) AS FloorValue;
-- نتیجه: 123
SELECT FLOOR(123.999) AS FloorValue;
-- نتیجه: 123
SELECT FLOOR(-123.456) AS FloorValue;
-- نتیجه: -124
**تابع گرد کردن سفارشی (Round Up Always)**
گاهی اوقات ممکن است نیاز داشته باشید که اعداد را به روشی متفاوت از آنچه تابع استاندارد `ROUND` در SQL Server انجام میدهد، گرد کنید. به عنوان مثال، اگر همیشه میخواهید 0.5 را به بالا (دور از صفر) گرد کنید، به جای گرد کردن به نزدیکترین عدد زوج (Banker’s Rounding)، میتوانید از یک تابع سفارشی استفاده کنید.
در اینجا یک تابع اسکالر سفارشی آورده شده است که میتوانید برای این منظور استفاده کنید. این تابع 0.5 را همیشه به سمت بالا گرد میکند، صرف نظر از اینکه عدد قبلی فرد است یا زوج:
CREATE FUNCTION dbo.udf_RoundUp
(
@value DECIMAL(38, 10),
@precision INT
)
RETURNS DECIMAL(38, 10)
AS
BEGIN
RETURN
CASE
WHEN @value >= 0 THEN FLOOR(@value * POWER(10, @precision) + 0.5) / POWER(10, @precision)
WHEN @value < 0 THEN CEILING(@value * POWER(10, @precision) - 0.5) / POWER(10, @precision)
END;
END;
برای استفاده از این تابع سفارشی، میتوانید آن را مانند هر تابع دیگری در کوئریهای خود فراخوانی کنید:
SELECT dbo.udf_RoundUp(2.5, 0);
-- نتیجه: 3.0000000000
SELECT dbo.udf_RoundUp(3.5, 0);
-- نتیجه: 4.0000000000
SELECT dbo.udf_RoundUp(4.5, 0);
-- نتیجه: 5.0000000000
SELECT dbo.udf_RoundUp(123.454, 2);
-- نتیجه: 123.4500000000
SELECT dbo.udf_RoundUp(123.456, 2);
-- نتیجه: 123.4600000000