在MySQL中,有可能像PHP那样绕半个特定方式吗?
**MenuItem3** = "/VoxeoCXP/DialogMapping/VSN/TelkomKioskService@System?vID=*643434c3c90606f20f9aa6510ff0d08907adf2001613e36cbc80909f59df7be2015010fc0561bc7a*"
PHP_ROUND_HALF_UP
PHP_ROUND_HALF_DOWN
PHP_ROUND_HALF_EVEN
http://php.net/manual/fr/function.round.php
或者我们真的只限于四舍五入?
答案 0 :(得分:3)
基于MySQL官方文档,舍入功能如下:
对于精确值数字,ROUND()使用“从零开始的一半” 或“向最近的方向”规则:具有0.5的小数部分的值 如果为正数或向下,则向上舍入到下一个整数 下一个整数,如果是负数。 (换句话说,它是圆形的 零。)小数部分小于.5的值向下舍入到 如果为正,则为下一个整数;如果为负,则为下一个整数。
http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_round
这意味着我们只能使用舍入函数来舍入。我编写了以下UDF来解决这个限制。
PHP_ROUND_HALF_ODD
注意:根据项目的需要,可以增加要舍入的数字的值,最多可达65位(在这种情况下,请不要忘记更改{{的所有实例)相应地)}。
https://stackoverflow.com/a/19201329/4949388
http://sandbox.onlinephpfunctions.com/code/054de06b074c2b3ece5fb6e5d4180524cd2207e2
CREATE FUNCTION roundHalf (
numberToRound DECIMAL(20,6),
roundingPrecision TINYINT(2),
roundingType ENUM (
'ROUND_HALF_UP',
'ROUND_HALF_DOWN',
'ROUND_HALF_EVEN',
'ROUND_HALF_ODD'
)
)
RETURNS DECIMAL(20,6)
BEGIN
DECLARE digitEvenOdd TINYINT (2) UNSIGNED DEFAULT 255;
DECLARE digitPosition TINYINT (2) UNSIGNED DEFAULT 0;
DECLARE digitToRound TINYINT (2) DEFAULT -1;
DECLARE roundedNumber DECIMAL(20,6) DEFAULT 0;
SET digitPosition = INSTR(numberToRound, '.');
IF (roundingPrecision < 1) THEN
SET digitPosition = digitPosition + roundingPrecision;
ELSE
SET digitPosition = digitPosition + roundingPrecision + 1;
END IF;
IF (digitPosition > 0 AND
digitPosition <= CHAR_LENGTH(numberToRound)
) THEN
SET digitToRound = CAST(
SUBSTR(
numberToRound,
digitPosition,
1
) AS UNSIGNED
);
SET digitPosition = digitPosition - 1;
IF (digitPosition > 0 AND
digitPosition <= CHAR_LENGTH(numberToRound)
) THEN
SET digitEvenOdd = CAST(
SUBSTR(
numberToRound,
digitPosition,
1
) AS UNSIGNED
);
END IF;
END IF;
IF (digitToRound > -1) THEN
CASE roundingType
WHEN 'ROUND_HALF_UP' THEN
IF (digitToRound >= 5) THEN
SET roundedNumber = ROUND(numberToRound, roundingPrecision);
ELSE
SET roundedNumber = TRUNCATE(numberToRound, roundingPrecision);
END IF;
WHEN 'ROUND_HALF_DOWN' THEN
IF (digitToRound > 5) THEN
SET roundedNumber = ROUND(numberToRound, roundingPrecision);
ELSE
SET roundedNumber = TRUNCATE(numberToRound, roundingPrecision);
END IF;
WHEN 'ROUND_HALF_EVEN' THEN
IF (digitToRound >= 5 AND
digitEvenOdd IN (1,3,5,7,9)
) THEN
SET roundedNumber = ROUND(numberToRound, roundingPrecision);
ELSE
SET roundedNumber = TRUNCATE(numberToRound, roundingPrecision);
END IF;
WHEN 'ROUND_HALF_ODD' THEN
IF (digitToRound >= 5 AND
digitEvenOdd IN (0,2,4,6,8)
) THEN
SET roundedNumber = ROUND(numberToRound, roundingPrecision);
ELSE
SET roundedNumber = TRUNCATE(numberToRound, roundingPrecision);
END IF;
END CASE;
ELSEIF (roundingPrecision > 0) THEN
SET roundedNumber = numberToRound;
END IF;
RETURN roundedNumber;
END //
随意使用该编码,但不要忘记喜欢我的帖子。谢谢大家的意见和建议。
答案 1 :(得分:1)
可以使用ROUND
函数在一行中完成四舍五入:
SELECT ROUND(ROUND({your_input_value}*2,0)/2,1);
ROUND({your_input_value}*2,0)
为您提供整数整数的舍入值。可以创建类似的其他轮次,包括向上,向下或其他乘数,如3,4等。
答案 2 :(得分:1)
MySQL中ROUND()
函数中存在一个错误很长一段时间它会返回不一致的结果,具体取决于它是否考虑输入值是否为精确或近似数字。至少记录了几个错误(请参阅here以及行为here的MySQL 5.7描述)。
我遇到了MySQL 5.6.22的问题,但从2001年的一些讨论来看,这似乎是非常普遍的。它似乎已经在2018年底的2018年初确定了,但我无法证明哪些版本有效正确,哪些没有。
以下是一种解决方法,无论<input_value>
是否被MySQL视为完全或近似数字:
SELECT ROUND(CAST(<input_value> AS DECIMAL(10,2)), 1)
如果您需要舍入到更多的圆形位置,请将第二个参数从ROUND()
更改为1
到您需要的小数位数,将第二个参数更改为DECIMAL()
来自{{} 1}}比你需要的小数位数高一个值。例如。您可以使用3位小数:
2
请注意,SELECT ROUND(CAST(<input_value> AS DECIMAL(10,4)), 3)
的第一个参数是数字中的总位数,因此,如果您需要存储较大的值,则可能需要相应地进行调整。有关详细信息,请参阅MySQL manual。
答案 3 :(得分:0)
如果在应用@Jonathan函数时遇到错误,则说:
Error 1418: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) SQL Statement:...
您应将DETERMINISTIC
或其他适用的声明放在BEGIN
之前
DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled