我有一个MySQL表estimate_item
,它包含几个包含固定精度的十进制值的列。这是我的表结构。
tableName:estimate_item
在使用PHP检索记录时,我使用MySQL的函数进行一些基本的计算,我使用的SQL查询就是这个。
SELECT
COUNT(ei.item_id) as total_item,
SUM(ei.quantity) as total_quantity,
SUM(ei.number_of_carton) as total_carton,
SUM(ei.number_of_carton * ei.cbm_per_carton) as total_cbm,
SUM(ei.quantity * ei.cost) as total_cost,
SUM(ei.quantity * ei.rate) as total_rate,
e.commission_amount,
SUM(ei.quantity * ei.rate) + e.commission_amount as total_amount
FROM
ai_estimate e
LEFT JOIN
ai_estimate_item ei ON ei.estimate_id = e.id
WHERE
ei.estimate_id = ?
例如上面的查询返回结果。
+------------+----------------+--------------+-----------+------------+------------+-------------------+--------------+
| total_item | total_quantity | total_carton | total_cbm | total_cost | total_rate | commission_amount | total_amount |
+------------+----------------+--------------+-----------+------------+------------+-------------------+--------------+
| 2 | 120 | 807 | 1122.6440 | 2.7500 | 137.5000 | 1500.00 | 1637.5000 |
+------------+----------------+--------------+-----------+------------+------------+-------------------+--------------+
由于以下列包含4个精度值total_cbm_total, total_cost, total_rate, total_amount
,我想以这种方式对所有四列的值进行舍入。
a)如果值为1122.6440
,则将其四舍五入为1122.644
b)如果值为2.7500
,则将其四舍五入为2.75
c)如果值为137.5000
,则将其四舍五入为137.50
d)如果值为1200.0000
,则将其四舍五入为1200.00
,即我希望这些值包含最少两个精度,根据值可以达到3或4精度。
有什么方法可以直接在MySQL中执行此操作吗?还是PHP方式?
感谢和问候。
答案 0 :(得分:1)
如果你在MySQL中这样做,我的猜测是你需要过度复杂的查询添加一个CASE WHEN ... END。
所以我会用PHP做到这一点。
function reprecise($value)
{
$two_digit = number_format($value, 2);
$three_digit = number_format($value, 3);
return (float)$two_digit == (float)$three_digit ? $two_digit : $three_digit;
}
这采用了一种技巧 - 首先它用两位和三位数计算表示,然后检查这些是否是相同的浮点数。如果是,那么三位数版本的最后一位必须为零,而是使用两位数版本。
要扩展到2,3或4位数,您可以在一个循环中执行此操作:
function reprecise($value)
{
$digits = 4;
for ($rep = number_format($value, $digits--); $digits >= 2; $digits--)
{
$new = number_format($value, $digits);
if ($new != $rep)
break;
$rep = $new;
}
return $rep;
}
或者,因为字符串函数很可能比number_format更快:
function reprecise($value)
{
$digits = 9;
$base = strrev(number_format($value, $digits));
for ($i = 0; $i < $digits-2; $i++)
if ($base[$i] != '0')
break;
return strrev(substr($base, $i));
}
答案 1 :(得分:1)
一种方法是使用正则表达式删除小数位后数字末尾的所有0
,然后格式化一个带有两位小数的数字并比较两个结果 - 返回最长的数字(字符串 - 明智的)。虽然这可以在mysql中完成,但在php中会更容易:
//$input - number to format
//$num - minimum number of decimal places to keep
function reformat($input, $num) {
$parse = preg_replace('/(\.[1-9]*)0+$/', "$1", $input);
$withmin = number_format($parse, 2);
return strlen($withmin) < strlen($parse) ? $parse : $withmin;
}
答案 2 :(得分:1)
数据库方面,请注意列cost,rate和cmb_per_carton的尾随0的数量是由表结构预定义的,在你的情况下是4 0s:
cost DECIMAL 19,4
rate DECIMAL 19,4
cmb_per_carton DECIMAL 19,4
如果您对这些字段进行操作,结果自然会有相同的尾随0。
PHP这边是一个简单的函数我刚刚入侵,它将完成你想要的东西:
function getDecimalFormatted($value, $minPrecision) {
$value = (float) $value;
return ((round((($value - floor($value))*pow(10, 5)))%1000) > 0) ? $value : number_format($value, $minPrecision, '.', '');
}
用法示例:
$value = "1234.71200";
echo getDecimalFormatted($value, 2)."\n<br>";
$value = "1234.70000";
echo getDecimalFormatted($value, 2)."\n<br>";
输出:
1234.712
1234.70