2009/03/01

MySQL ROUND() function

最近又需要將大批的數值資料進行四捨五入處理,無奈 MySQL 4.0 的 ROUND() 函式不能用,只好另外用 PHP 去處理,這遠比直接下 SQL 指令慢多了。

MySQL 4.0 的 ROUND() 函式不能用的原因是,ROUND(0.5) 預期會是 1,但是實際跑出來的結果卻是 0。
根據官方網站的說明,ROUND() 函式對數值得處理方式,取決於系統 C 函式庫的處理方式,而可能有以下幾種模式:

  1. round to the nearest even number

  2. always up

  3. always down

  4. always toward zero


不幸地,我的系統是採用第一種,對於 0.5 來說,最近的偶數是 0,因此 ROUND(0.5) 之後會得到 1。

官網上也有網友提出解決的方法,ROUND(X,D) 可以用以下公式替換:

TRUNCATE((X+SIGN(X)*(POW(10,(1-D))/18)), D)


到了 MySQL 5.0 之後,ROUND() 的實作方式也有了改進,根據官方網站的說明,ROUND() 對依據第一個輸入參數的型態進行不同的處理:

  • For exact-value numbers, ROUND() uses the “round half up” or “round toward nearest” rule: A value with a fractional part of .5 or greater is rounded up to the next integer if positive or down to the next integer if negative. (In other words, it is rounded away from zero.) A value with a fractional part less than .5 is rounded down to the next integer if positive or up to the next integer if negative.

  • For approximate-value numbers, the result depends on the C library. On many systems, this means that ROUND() uses the "round to nearest even" rule: A value with any fractional part is rounded to the nearest even integer.


如此 ROUND(0.5) 便會得到 1,這才是我想要的結果。

針對手邊現有的 FreeBSD 版本與 MySQL 版本進行測試,得到以下結果:










FreeBSD versionMySQL versionROUND(0.5)ok?
5.2.14.1.110X
5.34.0.240X
6.24.0.270X
6.25.0.451O
7.05.0.51a1O
7.04.0.270X
7.14.0.270X

的確,MySQL 5.0.45 之後的 ROUND() 函式比較好用了!

沒有留言:

張貼留言