読者です 読者をやめる 読者になる 読者になる

え〜と、小数点以下が可変桁数の値が文字列で入っているので、それを小数点以下2桁までで切り捨てたDECIMAL(10,2)の数値を取得したいのですが、既存のクエリは元々小数点以下3桁を想定していないから直接DECIMAL(10,2)に変換していてこれだと3位を四捨五入しちゃうというので手直ししてくれと言う話です。

これが誰かが作ったクエリ(一部)。

(CASE WHEN (ROW05 IS NULL AND ROW07 IS NULL AND ROW08 IS NULL) THEN NULL ELSE CAST(((CASE WHEN ROW05 IS NULL THEN '' ELSE ROW05 END) + (CASE WHEN ROW07 IS NULL THEN '' ELSE ROW07 END) + (CASE WHEN ROW08 IS NULL THEN '' ELSE ROW08 END)) AS DECIMAL(11,2)) END) AS 割合

CAST AS DECIMALでは強制四捨五入で切り捨てができないので、CASTする前にROUNDで切り捨てる(ROUNDの第2引数に1を渡すと切り捨て処理をする)。

(CASE WHEN (ROW05 IS NULL AND ROW07 IS NULL AND ROW08 IS NULL) THEN NULL ELSE CAST(ROUND(((CASE WHEN ROW05 IS NULL THEN '' ELSE ROW05 END) + (CASE WHEN ROW07 IS NULL THEN '' ELSE ROW07 END) + (CASE WHEN ROW08 IS NULL THEN '' ELSE ROW08 END)), 2, 1) AS DECIMAL(11,2)) END) AS 割合

で、修正したこのクエリを使うとデータが小数点以下2桁までしかないのに2桁目に誤差がでておかしい、と言うのでテストしたら、ROW05に「文字列」で数字が入っているとROUNDに渡されるときに自動キャストで浮動小数点に変換されて無限小数による切り捨て誤差をモロに受けるという orz

いろいろテストしたら、ROUNDに渡す前に2進化10進数にキャストすれば切り捨て時も2進化10進数で実行されるので宣言した桁数での正確さは保証される、模様なので、クエリを修正。
ただし、元データの小数点以下が可変なので、小数点以下の最大桁数を想定4桁として変換した後で改めて2桁に再変換する必要があります(宣言桁数未満は強制的に四捨五入されるため)。

(CASE WHEN (ROW05 IS NULL AND ROW07 IS NULL AND ROW08 IS NULL) THEN NULL ELSE CAST(ROUND(CAST((CASE WHEN ROW05 IS NOT NULL THEN ROW05 ELSE (CASE WHEN ROW07 IS NOT NULL THEN ROW07 ELSE ROW08 END) END) AS DECIMAL(13,5)), 2, 1) AS DECIMAL(10,2))) AS 割合

で、これがエラーで動かないのですがなんで動かないのかと調べたら条件判定の書式がおかしかったので修正。

(CASE WHEN (ROW05 IS NULL AND ROW07 IS NULL AND ROW08 IS NULL) THEN NULL ELSE CAST(ROUND(CAST((CASE WHEN ROW05 IS NOT NULL THEN ROW05 ELSE (CASE WHEN ROW07 IS NOT NULL THEN ROW07 ELSE ROW08 END) END) AS DECIMAL(13,5)), 2, 1) AS DECIMAL(10,2))END) AS 割合

動きました。

‥‥、

‥‥、

    _ □□    _      ___、、、
  //_   [][]//   ,,-―''':::::::::::::::ヽヾヽ':::::/、  誰  書 .   こ
//  \\  //  /::::::::::::::::::::::::::::::i l | l i:::::::ミ   だ   い   の
 ̄      ̄   ̄/ /:::::::::,,,-‐,/i/`''' ̄ ̄ ̄ `i::;|  あ.  た   ク
―`―--^--、__   /:::::::::=ソ   / ヽ、 /   ,,|/   っ  の   エ
/f ),fヽ,-、     ノ  | 三 i <ニ`-, ノ /、-ニニ' 」') !!  は   リ
  i'/ /^~i f-iノ   |三 彡 t ̄ 。` ソ ハ_゙'、 ̄。,フ | )          を
,,,     l'ノ j    ノ::i⌒ヽ;;|   ̄ ̄ / _ヽ、 ̄  ゙i )
  ` '' -  /    ノ::| ヽミ   `_,(_  i\_  `i ヽ、 ∧ ∧ ∧ ∧
     ///  |:::| ( ミ   / __ニ'__`i |  Y  Y Y Y Y
   ,-"        ,|:::ヽ  ミ   /-───―-`l  |  //     |
   |  //    l::::::::l\    ||||||||||||||||||||||/  |     // |
  /     ____.|:::::::|    、  `ー-―――┴ /    __,,..-'|
 /゙ー、,-―'''XXXX `''l::,/|    ー- 、__ ̄_,,-"、_,-''XXXXX |
/XX/ XXXXXXXXXX| |         _,  /ノXXXXXXXXXX|