Oracle で小数点以下を切り捨てるには TRUNC 関数または FLOOR 関数を使います。どちらも「端数を除去する」関数ですが、「TRUNC と FLOOR は何が違うのか」「十の位で切り捨てるにはどうするか」「消費税の端数を切り捨てたい」といった場面で迷うことは多いものです。
本記事では、TRUNC の桁指定(小数桁・整数桁の両方)を中心に、FLOOR との動作の違い(特に負の数)、金額端数切り捨て・消費税計算の実務パターン、任意単位での切り捨て(5 円単位・10 分単位など)まで体系的に解説します。
・TRUNC 関数の桁指定パラメータ(正の値 = 小数桁、負の値 = 整数桁)
・FLOOR 関数の基本動作
・TRUNC と FLOOR の違い(負の数での挙動差)
・十の位・百の位・千の位で切り捨てる方法
・消費税・割引の端数切り捨て実務パターン
・MOD と組み合わせた任意単位での切り捨て
・TRUNC / FLOOR / CEIL / ROUND の比較
TRUNC 関数の基本(数値の切り捨て)
TRUNC(数値 [, 桁数]) は、指定した桁数で数値を切り捨てます。桁数を省略すると 0(整数への切り捨て)として動作します。
-- 構文 TRUNC( 数値 [, 桁数] ) -- 整数への切り捨て(桁数省略 = 0) SELECT TRUNC(123.456) AS result FROM dual; -- 123 SELECT TRUNC(9.99) AS result FROM dual; -- 9 SELECT TRUNC(0.999) AS result FROM dual; -- 0 -- 小数第 1 位まで残す(桁数 = 1) SELECT TRUNC(123.456, 1) AS result FROM dual; -- 123.4 -- 小数第 2 位まで残す(桁数 = 2) SELECT TRUNC(123.456, 2) AS result FROM dual; -- 123.45 -- 小数第 3 位まで残す(桁数 = 3) SELECT TRUNC(123.4567, 3) AS result FROM dual; -- 123.456
桁指定パラメータの完全ガイド
TRUNC の第 2 引数は正の値で小数桁、負の値で整数桁を指定します。これは ROUND 関数の桁指定と同じ考え方です。
| 桁数 | 意味 | TRUNC(1234.567, n) の結果 |
|---|---|---|
| 3 | 小数第 3 位まで残す | 1234.567 |
| 2 | 小数第 2 位まで残す | 1234.56 |
| 1 | 小数第 1 位まで残す | 1234.5 |
| 0(省略時) | 整数にする | 1234 |
| -1 | 一の位を切り捨て(十の位まで残す) | 1230 |
| -2 | 十の位を切り捨て(百の位まで残す) | 1200 |
| -3 | 百の位を切り捨て(千の位まで残す) | 1000 |
-- 一の位を切り捨て(十の位まで残す) SELECT TRUNC(1234.567, -1) AS result FROM dual; -- 1230 -- 十の位を切り捨て(百の位まで残す) SELECT TRUNC(1234.567, -2) AS result FROM dual; -- 1200 -- 百の位を切り捨て(千の位まで残す) SELECT TRUNC(1234.567, -3) AS result FROM dual; -- 1000 -- 桁数が大きすぎる場合は 0 になる SELECT TRUNC(1234.567, -4) AS result FROM dual; -- 0
・桁数が正: 小数点の右を d 桁残す(残りを切り捨て)
・桁数が0: 小数部をすべて切り捨て(整数にする)
・桁数が負: 小数点の左を |d| 桁分切り捨てる(整数部が 0 に近づく)
この仕組みは ROUND 関数でもまったく同じです。
FLOOR 関数の基本
FLOOR(数値) は、引数の値以下で最大の整数を返します。TRUNC(n, 0) と似ていますが、負の数での動作が異なります。
-- FLOOR は「引数以下の最大整数」を返す(床関数) SELECT FLOOR(2.9) AS result FROM dual; -- 2 SELECT FLOOR(2.1) AS result FROM dual; -- 2 SELECT FLOOR(3.0) AS result FROM dual; -- 3(ちょうど整数ならそのまま) SELECT FLOOR(0.999) AS result FROM dual; -- 0
CEIL と同様に、FLOOR も常に整数への丸めです。
FLOOR(2.345, 2) のような書き方はエラーになります。任意の桁で切り捨てたい場合は TRUNC(桁指定可能)を使ってください。TRUNC と FLOOR の違い(負の数での挙動)
正の数では TRUNC と FLOOR の結果は同じですが、負の数では結果が異なります。これが最も重要な違いです。
SELECT
TRUNC(2.7) AS trunc_pos, -- 2(0方向に切り捨て)
FLOOR(2.7) AS floor_pos -- 2(-∞方向の最大整数)
FROM dual;
-- 正の数: どちらも同じ結果
SELECT
TRUNC(-2.3) AS trunc_neg, -- -2(0方向に切り捨て = 小数部を除去)
FLOOR(-2.3) AS floor_neg -- -3(-∞方向の最大整数)
FROM dual;
-- 負の数: TRUNC=-2, FLOOR=-3 で結果が異なる!
| 入力値 | TRUNC | FLOOR | TRUNC の方向 | FLOOR の方向 |
|---|---|---|---|---|
| 2.7 | 2 | 2 | → 0 方向 | → -∞ 方向(同じ) |
| -2.3 | -2 | -3 | → 0 方向 | → -∞ 方向 |
| -2.7 | -2 | -3 | → 0 方向 | → -∞ 方向 |
| -3.0 | -3 | -3 | ちょうど整数 | ちょうど整数(同じ) |
| 0.5 | 0 | 0 | → 0 方向(同じ) | → -∞ 方向(同じ) |
・TRUNC: 「小数部分を除去する」(符号に関係なく 0 方向に丸める)。金額の端数処理など、ほとんどの実務はこちら
・FLOOR: 「数直線上で必ず左(-∞ 方向)に丸める」。数学的な床関数が必要な場合(除算の商を求める等)に使う
正の数しか扱わない場合は、どちらを使っても同じ結果になります。
TRUNC / FLOOR / CEIL / ROUND の比較
| 入力値 | TRUNC | FLOOR | CEIL | ROUND |
|---|---|---|---|---|
| 2.3 | 2 | 2 | 3 | 2 |
| 2.5 | 2 | 2 | 3 | 3 |
| 2.7 | 2 | 2 | 3 | 3 |
| -2.3 | -2 | -3 | -2 | -2 |
| -2.5 | -2 | -3 | -2 | -3 |
| -2.7 | -2 | -3 | -2 | -3 |
| 関数 | 丸め方向 | 桁指定 | 主な用途 |
|---|---|---|---|
| TRUNC | 0 方向(小数部を捨てる) | あり(桁数指定可) | 金額端数切り捨て・桁揃え |
| FLOOR | -∞ 方向(常に小さい整数へ) | なし(整数のみ) | 数学的な床関数・除算の商 |
| CEIL | +∞ 方向(常に大きい整数へ) | なし(整数のみ) | ページ数・梱包数の計算 |
| ROUND | 最も近い値に丸める | あり(桁数指定可) | 四捨五入・一般的な丸め処理 |
ROUND 関数の詳細は「ROUND関数完全ガイド」、CEIL 関数の詳細は「CEIL関数で小数点以下を切り上げる方法」を参照してください。
実務パターン集
パターン①:消費税の端数切り捨て
-- 税抜価格 × 税率 の 1 円未満を切り捨て
SELECT
product_name,
price_excl_tax,
TRUNC(price_excl_tax * 0.10) AS tax_trunc,
price_excl_tax + TRUNC(price_excl_tax * 0.10) AS price_incl_tax
FROM products;
-- 結果例:
-- price_excl_tax=298 → 税=TRUNC(29.8)=29 → 税込327
-- price_excl_tax=980 → 税=TRUNC(98.0)=98 → 税込1078
-- price_excl_tax=100 → 税=TRUNC(10.0)=10 → 税込110
日本の消費税法では端数処理の方法は規定されておらず、切り捨て(TRUNC)・切り上げ(CEIL)・四捨五入(ROUND)のいずれも認められています。会計システムの仕様に合わせて使い分けてください。
パターン②:割引率適用後の金額を切り捨て
-- 単価 × (1 - 割引率) の端数を小数第 2 位で切り捨て
SELECT
product_name,
unit_price,
discount_rate,
TRUNC(unit_price * (1 - discount_rate), 2) AS discounted_price,
TO_CHAR(TRUNC(unit_price * (1 - discount_rate), 2),
'FM999,999,990.00') AS formatted
FROM products;
-- unit_price=1234.567, discount_rate=0.15 の場合:
-- 1234.567 * 0.85 = 1049.38195
-- TRUNC(1049.38195, 2) = 1049.38
パターン③:任意単位での切り捨て(5 円単位・100 円単位)
-- 5 円単位で切り捨て(1〜4円の端数を除去) SELECT TRUNC(298 / 5) * 5 AS result FROM dual; -- 295 SELECT TRUNC(302 / 5) * 5 AS result FROM dual; -- 300 -- 100 円単位で切り捨て SELECT TRUNC(1580 / 100) * 100 AS result FROM dual; -- 1500 -- 10 分単位で時間を切り捨て(勤怠管理) SELECT TRUNC(47 / 10) * 10 AS minutes FROM dual; -- 40(47分→40分) -- TRUNC の負の桁を使う方法(100円単位で切り捨て) SELECT TRUNC(1580, -2) AS result FROM dual; -- 1500 -- → TRUNC(n / 100) * 100 と同じ結果だが、こちらの方がシンプル
・10 / 100 / 1000 など 10 の累乗単位 →
TRUNC(n, 負の桁数) がシンプル・5 / 15 / 30 など 10 の累乗でない単位 →
TRUNC(n / 単位) * 単位 を使うパターン④:GROUP BY での金額帯集計
-- 1000 円単位で切り捨てて金額帯を作る
SELECT
TRUNC(amount, -3) AS amount_band,
COUNT(*) AS order_count,
SUM(amount) AS total_amount
FROM orders
GROUP BY TRUNC(amount, -3)
ORDER BY amount_band;
-- 結果例:
-- amount_band=0 → 1〜999円の注文
-- amount_band=1000 → 1000〜1999円の注文
-- amount_band=5000 → 5000〜5999円の注文
-- 年齢帯での集計(10歳刻みで切り捨て)
SELECT
TRUNC(age, -1) AS age_band, -- 20, 30, 40 ...
COUNT(*) AS user_count
FROM users
GROUP BY TRUNC(age, -1)
ORDER BY age_band;
パターン⑤:小数第 n 位以下を切り捨てた結果を表示する
-- 小数第 2 位で切り捨て + カンマ付き表示
SELECT
product_name,
TRUNC(unit_price, 2) AS truncated,
TO_CHAR(TRUNC(unit_price, 2), 'FM999,999,990.00') AS formatted
FROM products;
-- TRUNC(123.4, 2) = 123.4 → TO_CHAR で '123.40' と表示
-- TRUNC で末尾のゼロが消える場合は TO_CHAR で書式指定
TO_CHAR の数値書式モデルについては「小数点以下の0が消える原因と表示する方法」を参照してください。
UPDATE で既存データの端数を一括切り捨て
-- ステップ 1: 対象データの確認
SELECT id, price,
TRUNC(price, 2) AS truncated_price
FROM products
WHERE price <> TRUNC(price, 2); -- 小数第3位以下がある行
-- ステップ 2: UPDATE
UPDATE products
SET price = TRUNC(price, 2)
WHERE price <> TRUNC(price, 2);
-- ステップ 3: COMMIT
COMMIT;
-- 複数カラムを同時に処理
UPDATE order_details
SET unit_price = TRUNC(unit_price, 2),
discount_amt = TRUNC(discount_amt, 0), -- 整数に切り捨て
tax_amount = TRUNC(tax_amount, 0)
WHERE unit_price <> TRUNC(unit_price, 2)
OR discount_amt <> TRUNC(discount_amt, 0)
OR tax_amount <> TRUNC(tax_amount, 0);
TRUNC の日付への適用について
TRUNC は数値だけでなく日付(DATE 型)にも使えます。TRUNC(SYSDATE) で時刻部分を切り捨てて 00:00:00 にする、TRUNC(date, 'MM') で月初 1 日にするなど、日付集計で頻繁に使われます。
日付に対する TRUNC の詳細は「TRUNC関数で日付を切り捨てる方法」を参照してください。
よくある質問
TRUNC(NULL) は NULL を返します。TRUNC(NULL, 2)・FLOOR(NULL) も同様です。NULL の可能性があるカラムでも事前の NULL チェックは不要です。TRUNC(1.5, 2) の結果は NUMBER 型の 1.5 です。NUMBER 型は意味のない末尾ゼロを保持しません。「1.50」と表示したい場合は TO_CHAR(TRUNC(1.5, 2), 'FM990.00') で書式を指定してください。TRUNC(n / 5) * 5 で実現できます。298 → TRUNC(59.6) * 5 = 59 * 5 = 295 になります。同様に、15 分単位なら TRUNC(minutes / 15) * 15、50 円単位なら TRUNC(price / 50) * 50 と応用できます。NUMBER 型を使用してください。まとめ
Oracle の切り捨て処理の要点をまとめます。
| やりたいこと | 使う式 |
|---|---|
| 整数への切り捨て | TRUNC(n) または FLOOR(n) |
| 小数第 1 位まで残す | TRUNC(n, 1) |
| 小数第 2 位まで残す | TRUNC(n, 2) |
| 十の位で切り捨て | TRUNC(n, -1) |
| 百の位で切り捨て | TRUNC(n, -2) |
| 5 円単位で切り捨て | TRUNC(n / 5) * 5 |
| 100 円単位で切り捨て | TRUNC(n, -2) または TRUNC(n / 100) * 100 |
| 消費税の端数切り捨て | TRUNC(price * tax_rate) |
| 金額帯での GROUP BY | GROUP BY TRUNC(amount, -3) |
| 負の数で -∞ 方向に丸め | FLOOR(n)(TRUNC とは結果が異なる) |
日付の切り捨てについては「TRUNC関数で日付を切り捨てる方法」、切り上げについては「CEIL関数で小数点以下を切り上げる方法」、四捨五入については「ROUND関数完全ガイド」も併せて参照してください。
