LoginSignup
3
1

More than 3 years have passed since last update.

Oracle Databaseのround()の話

Last updated at Posted at 2019-12-13

この記事は PostgreSQLのround()の話 に触発されて、Oracle Databaseでも同様の調査を行った結果です。

ROUND 関数による丸め

Oracle Database の ROUND 関数は他のデータベースと同様に数値を丸めるために使われます。しかし、データ型によって整数に丸めた場合の結果が変化します。NUMBER 型とBINARY_DOUBLE 型の列に値を格納して結果を確認します。

SQL> CREATE TABLE rd_table(c1 NUMBER(3, 1), c2 BINARY_DOUBLE);
Table created.

SQL> INSERT INTO rd_table VALUES (2.1, 2.1);
1 row created.

SQL> INSERT INTO rd_table VALUES (2.2, 2.2);
1 row created.

...

SQL> INSERT INTO rd_table VALUES (2.9, 2.9);
1 row created.

SQL> INSERT INTO rd_table VALUES (3.0, 3.0);
1 row created.

SQL> COMMIT
Commit complete.

整数値に変換するために、ROUND 関数を実行します。

SQL> SELECT c1, ROUND(c1), c2, ROUND(c2) FROM rd_table ORDER BY c1;

        C1  ROUND(C1)         C2  ROUND(C2)
---------- ---------- ---------- ----------
       2.1          2   2.1E+000   2.0E+000
       2.2          2   2.2E+000   2.0E+000
       2.3          2   2.3E+000   2.0E+000
       2.4          2   2.4E+000   2.0E+000
       2.5          3   2.5E+000   2.0E+000
       2.6          3   2.6E+000   3.0E+000
       2.7          3   2.7E+000   3.0E+000
       2.8          3   2.8E+000   3.0E+000
       2.9          3   2.9E+000   3.0E+000
         3          3   3.0E+000   3.0E+000

10 rows selected.

NUMBER 型の 2.5 に対して ROUND 関数を実行すると 3 になるのに対し、BINARY_DOUBLE 型の 2.5 に対してROUND 関数を実行すると 2.0 になっています。これは「銀行丸め」とか「偶数への丸め」と呼ばれる仕様です。端数が 0.5 の場合は偶数になるように丸めます。

ROUND(v) と ROUND(v, 0) の違い

ROUND 関数の第2パラメーターには小数点以下の桁数を指定します。この値を 0 に指定すると整数に丸められますが、BINARY_DOUBLE 型の列に対して実行すると結果が変わってきます。

SQL> SELECT c2, ROUND(c2), ROUND(c2, 0) FROM rd_table ORDER BY c1;

        C2  ROUND(C2) ROUND(C2,0)
---------- ---------- -----------
  2.1E+000   2.0E+000           2
  2.2E+000   2.0E+000           2
  2.3E+000   2.0E+000           2
  2.4E+000   2.0E+000           2
  2.5E+000   2.0E+000           3
  2.6E+000   3.0E+000           3
  2.7E+000   3.0E+000           3
  2.8E+000   3.0E+000           3
  2.9E+000   3.0E+000           3
  3.0E+000   3.0E+000           3

10 rows selected.

c2 列が 2.4 の場合、ROUND(c2) は 2.0 が返りますが、ROUND(c2, 0) は 3 が返っています。
これは第2パラメーターに 0 を指定した場合、NUMBER 型として扱われるためです。
マニュアル には下記ようにわかりにくい記述があります。

nには、任意の数値データ型、または暗黙的に数値データ型に変換可能な数値以外のデータ型を指定できます。integerを指定しない場合、このファンクションは、nの数値データ型と同じデータ型で値ROUND(n, 0)を戻します。integerを指定すると、このファンクションはNUMBERを戻します。

他のRDBMSでは?

SQL Server や DB2 ではNUMERIC 型、FLOAT 型共に四捨五入がデフォルトになるようです。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1