【Oracle】TRUNC / FLOOR で小数点以下を切り捨てる方法|桁指定・負の数・端数処理・実務パターンまで解説

【Oracle】TRUNC / FLOOR で小数点以下を切り捨てる方法|桁指定・負の数・端数処理・実務パターンまで解説 Oracle

Oracle で小数点以下を切り捨てるには TRUNC 関数または FLOOR 関数を使います。どちらも「端数を除去する」関数ですが、「TRUNC と FLOOR は何が違うのか」「十の位で切り捨てるにはどうするか」「消費税の端数を切り捨てたい」といった場面で迷うことは多いものです。

本記事では、TRUNC の桁指定(小数桁・整数桁の両方)を中心に、FLOOR との動作の違い(特に負の数)、金額端数切り捨て・消費税計算の実務パターン任意単位での切り捨て(5 円単位・10 分単位など)まで体系的に解説します。

この記事でわかること
・TRUNC 関数の桁指定パラメータ(正の値 = 小数桁、負の値 = 整数桁)
・FLOOR 関数の基本動作
・TRUNC と FLOOR の違い(負の数での挙動差)
・十の位・百の位・千の位で切り捨てる方法
・消費税・割引の端数切り捨て実務パターン
・MOD と組み合わせた任意単位での切り捨て
・TRUNC / FLOOR / CEIL / ROUND の比較
スポンサーリンク

TRUNC 関数の基本(数値の切り捨て)

TRUNC(数値 [, 桁数]) は、指定した桁数で数値を切り捨てます。桁数を省略すると 0(整数への切り捨て)として動作します。

SQL(TRUNC 基本)
-- 構文
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
SQL(負の桁数で整数部を切り捨て)
-- 一の位を切り捨て(十の位まで残す)
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
TRUNC の桁指定の覚え方
・桁数が: 小数点のを d 桁残す(残りを切り捨て)
・桁数が0: 小数部をすべて切り捨て(整数にする)
・桁数が: 小数点のを |d| 桁分切り捨てる(整数部が 0 に近づく)
この仕組みは ROUND 関数でもまったく同じです。

FLOOR 関数の基本

FLOOR(数値) は、引数の値以下で最大の整数を返します。TRUNC(n, 0) と似ていますが、負の数での動作が異なります

SQL(FLOOR 基本)
-- 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
FLOOR には桁数指定がない
CEIL と同様に、FLOOR も常に整数への丸めです。FLOOR(2.345, 2) のような書き方はエラーになります。任意の桁で切り捨てたい場合は TRUNC(桁指定可能)を使ってください。

TRUNC と FLOOR の違い(負の数での挙動)

正の数では TRUNC と FLOOR の結果は同じですが、負の数では結果が異なります。これが最も重要な違いです。

SQL(正の数: 結果は同じ)
SELECT
    TRUNC(2.7) AS trunc_pos,   -- 2(0方向に切り捨て)
    FLOOR(2.7) AS floor_pos    -- 2(-∞方向の最大整数)
FROM dual;
-- 正の数: どちらも同じ結果
SQL(負の数: 結果が異なる)
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関数で小数点以下を切り上げる方法」を参照してください。

実務パターン集

パターン①:消費税の端数切り捨て

SQL(消費税の端数切り捨て)
-- 税抜価格 × 税率 の 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)のいずれも認められています。会計システムの仕様に合わせて使い分けてください。

パターン②:割引率適用後の金額を切り捨て

SQL(割引後金額の切り捨て)
-- 単価 × (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 円単位)

SQL(任意単位での切り捨て)
-- 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 と同じ結果だが、こちらの方がシンプル
任意単位 vs 桁指定の使い分け
・10 / 100 / 1000 など 10 の累乗単位 → TRUNC(n, 負の桁数) がシンプル
・5 / 15 / 30 など 10 の累乗でない単位 → TRUNC(n / 単位) * 単位 を使う

パターン④:GROUP BY での金額帯集計

SQL(金額帯で集計)
-- 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 位以下を切り捨てた結果を表示する

SQL(切り捨て + TO_CHAR で表示整形)
-- 小数第 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 で既存データの端数を一括切り捨て

SQL(一括端数切り捨て)
-- ステップ 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関数で日付を切り捨てる方法」を参照してください。

よくある質問

QTRUNC と FLOOR はどちらを使うべきですか?
Aほとんどのケースで TRUNC を推奨します。理由は 2 つあります。①桁数指定ができる(FLOOR は整数への丸めのみ)、②正の数のみを扱う場合は結果が同じ。負の数で「数直線上の左方向(-∞ 方向)」に丸めたい場合のみ FLOOR を使います。金額計算で負の値が出ない場合は TRUNC で統一するのがシンプルです。
QTRUNC(NULL) はエラーになりますか?
Aエラーにはなりません。TRUNC(NULL)NULL を返します。TRUNC(NULL, 2)FLOOR(NULL) も同様です。NULL の可能性があるカラムでも事前の NULL チェックは不要です。
QTRUNC(1234.567, -4) は 0 になります。なぜですか?
A桁数 -4 は「千の位を切り捨て(万の位まで残す)」という意味です。1234 は万の位が 0 なので、結果は 0 になります。入力値の桁数より大きい負の桁数を指定すると、常に 0 になります。
QTRUNC で小数第 2 位まで残したのに末尾のゼロが消えます
ATRUNC(1.5, 2) の結果は NUMBER 型の 1.5 です。NUMBER 型は意味のない末尾ゼロを保持しません。「1.50」と表示したい場合は TO_CHAR(TRUNC(1.5, 2), 'FM990.00') で書式を指定してください。
Q5 円単位で切り捨てる方法はありますか?
ATRUNC(n / 5) * 5 で実現できます。298 → TRUNC(59.6) * 5 = 59 * 5 = 295 になります。同様に、15 分単位なら TRUNC(minutes / 15) * 15、50 円単位なら TRUNC(price / 50) * 50 と応用できます。
QBINARY_FLOAT 型で TRUNC を使うと結果がおかしいです
ABINARY_FLOAT / BINARY_DOUBLE は IEEE 754 浮動小数点型で、十進数では正確に表現できない値があります。TRUNC が浮動小数点の内部表現に基づいて動作するため、意図しない桁が残る(または消える)ことがあります。金額計算では必ず 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関数完全ガイド」も併せて参照してください。