【Oracle】四捨五入を行う方法|ROUND関数の全機能・桁指定・日付丸め・TRUNC/CEIL/FLOORとの比較

【Oracle】四捨五入を行う方法|ROUND関数の全機能・桁指定・日付丸め・TRUNC/CEIL/FLOORとの比較 Oracle

Oracle で数値を四捨五入するには ROUND 関数を使います。小数点以下の桁数指定だけでなく、十の位・百の位での丸めや日付への適用まで幅広く使えます。本記事では基本から実務パターンまでを体系的に解説します。

この記事で解決できること

  • ROUND 関数の構文と基本的な四捨五入の使い方
  • 小数点以下 n 桁・整数部分(十の位・百の位)での丸め
  • 日付に対する ROUND(月初・年初・週単位など)
  • TRUNC・CEIL・FLOOR との違いと使い分け
  • 金融計算・消費税計算での実務パターン
  • 負の数値に対する ROUND の動作
スポンサーリンク

ROUND 関数の構文

ROUND(n [, integer])
引数 説明
n NUMBER / DATE 丸め対象の数値または日付
integer NUMBER(省略可) 丸める桁位置。省略時は 0(整数に丸め)
integer の正負で丸める位置が変わる
integer が正の場合は小数点以下の桁、負の場合は整数部分の桁で丸めます。
例:ROUND(1234.567, 1) → 小数第 1 位で丸め → 1234.6
例:ROUND(1234.567, -2) → 百の位で丸め → 1200

基本的な使い方

小数点以下で四捨五入

-- 整数に丸める(integer 省略 = 0 と同じ)
SELECT ROUND(3.5)   FROM DUAL;  -- 結果: 4
SELECT ROUND(3.4)   FROM DUAL;  -- 結果: 3
SELECT ROUND(3.45)  FROM DUAL;  -- 結果: 3

-- 小数第 1 位で丸める
SELECT ROUND(3.45, 1)  FROM DUAL;  -- 結果: 3.5
SELECT ROUND(3.44, 1)  FROM DUAL;  -- 結果: 3.4

-- 小数第 2 位で丸める
SELECT ROUND(3.456, 2)  FROM DUAL;  -- 結果: 3.46
SELECT ROUND(3.454, 2)  FROM DUAL;  -- 結果: 3.45

-- 小数第 3 位で丸める
SELECT ROUND(3.4565, 3)  FROM DUAL;  -- 結果: 3.457
SELECT ROUND(3.4564, 3)  FROM DUAL;  -- 結果: 3.456

整数部分で四捨五入(負の桁指定)

-- 十の位で丸める(integer = -1)
SELECT ROUND(1234.5, -1)  FROM DUAL;  -- 結果: 1230
SELECT ROUND(1235.0, -1)  FROM DUAL;  -- 結果: 1240

-- 百の位で丸める(integer = -2)
SELECT ROUND(1250, -2)    FROM DUAL;  -- 結果: 1300
SELECT ROUND(1249, -2)    FROM DUAL;  -- 結果: 1200

-- 千の位で丸める(integer = -3)
SELECT ROUND(1500, -3)    FROM DUAL;  -- 結果: 2000
SELECT ROUND(1499, -3)    FROM DUAL;  -- 結果: 1000

負の数値に対する ROUND

-- 負の数値は絶対値で四捨五入して符号を戻す
SELECT ROUND(-3.5)    FROM DUAL;  -- 結果: -4
SELECT ROUND(-3.4)    FROM DUAL;  -- 結果: -3
SELECT ROUND(-3.45, 1) FROM DUAL; -- 結果: -3.5
SELECT ROUND(-1250, -2) FROM DUAL; -- 結果: -1300
ちょうど半分(.5)の場合は「0 から遠い方向」に丸める
Oracle の ROUND は「.5 の場合、絶対値が大きくなる方向」に丸めます。
ROUND(2.5)3(正の方向に丸め上げ)
ROUND(-2.5)-3(負の方向に丸め下げ)
いわゆる「数学的四捨五入」であり、銀行家の丸め(Banker’s Rounding)とは異なります。

テーブルのカラムに対して使う

-- 商品価格を百円単位で丸めて表示
SELECT
  product_name,
  price,
  ROUND(price, -2)          AS price_rounded_100,
  ROUND(price * 1.10, 0)    AS price_with_tax
FROM products;

-- 平均値を小数第 2 位に丸める
SELECT
  department_id,
  ROUND(AVG(salary), 2)  AS avg_salary
FROM employees
GROUP BY department_id
ORDER BY department_id;

ROUND・TRUNC・CEIL・FLOOR の違い

数値を丸める関数は4種類あります。目的に合わせて使い分けてください。

関数 動作 3.5 3.4 -3.5 -3.4
ROUND(n) 四捨五入(.5 は絶対値大の方向) 4 3 -4 -3
TRUNC(n) 切り捨て(0 方向に切り捨て) 3 3 -3 -3
CEIL(n) 切り上げ(数直線の右方向へ) 4 4 -3 -3
FLOOR(n) 切り捨て(数直線の左方向へ) 3 3 -4 -4
TRUNC と FLOOR の違い
正の数では同じ結果ですが、負の数で挙動が異なります
TRUNC(-3.5)-3(0 に近い方向 = 切り捨て)
FLOOR(-3.5)-4(数直線の左方向 = より小さい整数)
「小数を取り除く」には TRUNC、「以下の最大整数」には FLOOR を使います。

日付への ROUND

ROUND は日付にも使えます。第 2 引数にフォーマット文字列を指定することで、月初・年初・週単位などに丸めることができます。

-- 月単位で丸める(15 日以降なら翌月 1 日、14 日以前なら今月 1 日)
SELECT ROUND(DATE '2024-07-16', 'MM') FROM DUAL;  -- 結果: 2024-08-01
SELECT ROUND(DATE '2024-07-14', 'MM') FROM DUAL;  -- 結果: 2024-07-01

-- 年単位で丸める(7 月以降なら翌年 1 月 1 日)
SELECT ROUND(DATE '2024-07-01', 'YYYY') FROM DUAL;  -- 結果: 2025-01-01
SELECT ROUND(DATE '2024-06-30', 'YYYY') FROM DUAL;  -- 結果: 2024-01-01

-- 週単位で丸める(NLS の週開始曜日に近い週の開始日、デフォルト日曜日)
SELECT ROUND(DATE '2024-07-17', 'DAY') FROM DUAL;  -- 結果: 2024-07-21(直近の日曜日、NLS依存)
SELECT ROUND(DATE '2024-07-17', 'DY')  FROM DUAL;  -- 結果: 同上

-- 時刻を時間単位で丸める
SELECT ROUND(SYSDATE, 'HH') FROM DUAL;  -- 現在時刻を時間単位に丸める

日付 ROUND の主なフォーマット文字列

フォーマット 丸め単位 境界(この日時以降なら次の単位)
YYYY / YEAR 7 月 1 日 00:00:00
Q 四半期 四半期の第 2 月の 16 日
MM / MONTH 16 日 00:00:00
WW 週(年の第 1 日と同じ曜日) 週の中間
DAY / DY 週(NLS_TERRITORY の週開始曜日、デフォルト日曜日) 週の中間日(木曜日 00:00:00)
DD 12:00:00
HH / HH12 / HH24 時間 30 分 00 秒
MI 30 秒

実務パターン集

消費税計算(1円未満の端数処理)

-- 消費税込み金額を計算(1 円未満を四捨五入)
SELECT
  product_name,
  price,
  ROUND(price * 1.10)  AS price_with_tax_round,   -- 四捨五入
  TRUNC(price * 1.10)  AS price_with_tax_trunc,   -- 切り捨て
  CEIL(price * 1.10)   AS price_with_tax_ceil      -- 切り上げ
FROM products;

売上集計レポート(百万円単位で表示)

-- 百万円単位に丸めてレポート表示
SELECT
  department_id,
  ROUND(SUM(amount), -6)         AS total_round_m,    -- 百万円単位で四捨五入
  ROUND(SUM(amount) / 1000000, 1) AS total_million     -- 百万円で割って小数第 1 位まで
FROM sales
GROUP BY department_id
ORDER BY total_round_m DESC;

月初・月末の集計(日付 ROUND と TRUNC の組み合わせ)

-- 当月データを集計(TRUNC で月初を求める)
SELECT COUNT(*), SUM(amount)
FROM orders
WHERE order_date >= TRUNC(SYSDATE, 'MM')           -- 今月 1 日 00:00:00
  AND order_date <  ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1);  -- 翌月 1 日

-- 時間帯別の集計(1 時間単位に丸める)
SELECT
  ROUND(order_time, 'HH')  AS hour_block,
  COUNT(*)                 AS order_count
FROM orders
WHERE TRUNC(order_time) = TRUNC(SYSDATE)
GROUP BY ROUND(order_time, 'HH')
ORDER BY hour_block;

よくある質問(FAQ)

Q ROUND(2.5) が 3 で、ROUND(3.5) も 4 になるのはなぜ?銀行家の丸めではないの?
A

Oracle の ROUND は「.5 の場合は 0 から遠い方(絶対値が大きくなる方)」に丸める一般的な四捨五入です。銀行家の丸め(偶数丸め: .5 を偶数側に丸める)は Oracle では標準実装されていません。

銀行家の丸めが必要な場合は CASE 式で実装できます。

-- 銀行家の丸め(偶数丸め)の実装例
SELECT
  n,
  CASE
    WHEN n - TRUNC(n) = 0.5 AND MOD(TRUNC(n), 2) = 0
      THEN TRUNC(n)    -- .5 かつ整数部が偶数 → 切り捨て
    ELSE ROUND(n)      -- それ以外は通常の四捨五入
  END AS bankers_round
FROM (SELECT 2.5 AS n FROM DUAL UNION ALL
      SELECT 3.5 FROM DUAL UNION ALL
      SELECT 4.5 FROM DUAL);
Q ROUND で小数点以下が消えない。NUMBER 型の精度が原因?
A

ROUND(1.005, 2)1.00 になる場合、浮動小数点の精度問題ではなく、列の定義が NUMBER(10,2) のように 2 桁精度に制限されているため 1.005 が格納時点で 1.01 または 1.00 に丸められている可能性があります。

また FLOAT 型は 2 進浮動小数点のため 1.005 が内部的に 1.00499999... になることがあります。金融計算は NUMBER 型を明示的に使ってください。

Q ROUND と TO_CHAR での丸めの違いは?
A

TO_CHAR(1.567, 'FM9990.00') のようにフォーマット指定で表示桁数を制限すると四捨五入されたように見えます。ただしこれは 表示上の丸め であり、演算には元の値が使われます。

計算結果として丸めた値を使いたい場合は必ず ROUND を使ってください。TO_CHAR は表示専用です。

Q 日付の ROUND で「DAY」と「DD」の違いは?
A

'DD' は「日」単位で丸め、正午(12:00)を境界に当日の 00:00 か翌日の 00:00 に丸めます。
'DAY'(または 'DY')は「週」単位で丸め、NLS の週開始曜日(デフォルト日曜日)に近い週の開始日に丸めます。

日付の時刻部分を取り除いて「日付のみ」にしたい場合は ROUND(date, 'DD') より TRUNC(date) が一般的です。

Q ROUND の結果を WHERE 句で使うときにインデックスは使われる?
A

WHERE ROUND(salary, -3) = 10000 のようにインデックスが付いた列を関数で囲むと、通常のインデックスは使われません(インデックスが列値でなく関数結果でないため)。

頻繁に使うなら ファンクションベースインデックス(Function-Based Index)を作成してください。

-- ファンクションベースインデックスを作成
CREATE INDEX idx_salary_round ON employees (ROUND(salary, -3));

-- このクエリでインデックスが使われるようになる
SELECT * FROM employees WHERE ROUND(salary, -3) = 10000;

まとめ

やりたいこと 関数・構文
整数に四捨五入 ROUND(n) ROUND(3.5) → 4
小数第 n 位で四捨五入 ROUND(n, 桁数) ROUND(3.456, 2) → 3.46
十・百の位で丸め ROUND(n, -1) / ROUND(n, -2) ROUND(1250, -2) → 1300
切り捨て(0 方向) TRUNC(n, 桁数) TRUNC(3.9) → 3
切り上げ(数直線右) CEIL(n) CEIL(3.1) → 4
切り捨て(数直線左) FLOOR(n) FLOOR(-3.1) → -4
月初に丸める TRUNC(date, 'MM') 今月 1 日 00:00:00
月単位で四捨五入 ROUND(date, 'MM') 16 日以降なら翌月 1 日

Oracle の四捨五入は ROUND(n, integer) の 1 関数で、小数点以下から百の位まで柔軟に対応できます。日付への適用もでき、月初の計算などでも活躍します。TRUNC・CEIL・FLOOR との使い分けを押さえておくと、端数処理のあらゆる要件に対応できます。