集計処理と端数処理、どっちが先か

ORACLE
20160126-1

集計処理と端数処理の順番の考慮が重要になることがあります。処理順によって、計算結果が変わってくる事があるためです。
これはORACLEに限った話ではありませんが、SQLを記述する際にも考慮が必要な話なので、本記事にまとめました。

集計処理と端数処理の順番による差異

集計処理と端数処理の順番で、計算結果が変わることがあります。具体的な例で見てみましょう。

-- データ
NO WEIGHT
-- ------
 1   60.1
 2   72.2
 3   51.0
 4   89.2

-- 重量(WEIGHT)を集計した後、端数処理(四捨五入)した場合
SELECT ROUND(SUM(weight)) sum_weight FROM test_table;

SUM_WEIGHT
----------
       273

-- 重量(WEIGHT)を端数処理(四捨五入)した後、集計した場合
SELECT SUM(ROUND(weight)) sum_weight FROM test_table;

SUM_WEIGHT
----------
       272

計算結果が変わることがわかります。

要件を確認しよう

このあたりの計算方法は、仕様をユーザーに確認しましょう。思い込みで設計すると、本来の仕様と異なっているかもしれません。

例えば、厳密に決められていると何となく思ってしまう消費税の計算すら、企業によって異なっている場合があります。(端数処理自体も切捨て、四捨五入、切上げと好きに選んでよいのです。大体は切捨てですが。)

●データ
NO  PRICE
-- ------
 1    110
 2    120
 3    130

●金額(PRICE)に税率(8%)を掛けて端数処理(切捨て)、その後合計
  ⇒118(110×1.08=118.8)+129(120×1.08=129.6)+140(130×1.08=140.4)
  ⇒387

●金額(PRICE)を合計した後、税率(8%)を掛けて端数処理(切捨て)
  ⇒(110+120+130)×1.08=140.4
  ⇒388(360×1.08=388.8)

消費税に限らず、集計処理と端数処理の順番は単体テストや結合テストで発見できない事が多いです。正しいと思い込んでいるシステム構築担当がテストケースの作成&実施をするためです。

ではユーザーの受入テストで見つけられるのか、といえばそれも怪しいです。実際のテストデータはシステム構築担当が用意したり、ユーザー側もそこまで細かいパターンを確認しないという場合も多いためです。

最悪、本番化してから障害発覚という最悪のケースも想定されます。

まとめ

集計処理と端数処理の順番について、重要であることが分かっていただけたと思います。

SQL内では端数処理しかせずに、外側の処理で集計しているというケースもあります。
また整数しか保持できない変数に代入することで、暗黙的に端数処理がされているケースもあります。

意識して設計をしましょう。

タイトルとURLをコピーしました