先日からSQLの記事を書いていますが、今回も同じくSQLの記事です。
環境はOracle19c。
もくじ
2.引数の注意点
3.参考:類似関数
1.DECODE関数とは
取得したデータ値を、別の値に置き換えて返却するための関数。
構文は以下の通り。
DECODE( 列名, 値A, 値Aの置換後の値, 値B, 値Bの置換後の値, …, デフォルト値 )
例えば以下のように用いる。
SELECT DECODE( COLUMN_A, 'りんご', 'apple', 'みかん', 'orange', 'もも', 'peach', '対象外' ) FROM …
例であれば、
取得してきたCOLUMN_A列の値が、
・「りんご」だった場合→「apple」に置き換えて値を返却する
・「みかん」だった場合→「orannge」に置き換えて値を返却する
・「もも」だった場合→「peach」に置き換えて値を返却する
・どれにも当てはまらなかった場合→「対象外」と返却する
という挙動になる。
なお、あくまで返却値を指定した値に置き換えるだけであり、
DBのデータそのものを置換するわけではない。
2.引数の注意点
DECODE関数の引数について、4つ注意点がある。
■①引数の最大個数
DECODE関数に渡せる引数は、最大で256個までである。
256個は、
・対象の列名
・値X
・値Xの置換後の値)
・どれにも当てはまらなかった時用の値(デフォルトの値)
の総計である。
従って、対象の列名・デフォルトの値を差し引くと、
実質254個(ペアと考えると137)までの置き換え指定が可能という計算になる。
とはいえ、実コードを考えたときに、
さすがに137ペアもずらずらと値を書き連ねるようなことはないと思うので(あったら衝撃…(;^_^A)、
引数の最大個数はあまり気にしなくてよいと思う。
■②引数の順番に注意
DECODE関数では、渡された列の値に対して、1つずつ前から順番に評価していく。
合致する値を見つけたら、以降の値が合致するかどうかの評価は行わない。
前述の例で、COLUMN_Aの値が「みかん」だった場合を考えてみる。
SELECT DECODE( COLUMN_A, 'りんご', 'apple', 'みかん', 'orange', 'もも', 'peach', '対象外' ) FROM …
この場合、「りんご」→「みかん」の順に、頭から合致する値を探索することになる。
2つ目の「みかん」で値が合致するため、以降の「もも」の値が列の値と合致するかは確認せず、「orange」を直ちに返す。
ただしDECODE関数は、演算子や正規表現などによる値の指定ができないため、
基本的に、「りんご」、「みかん」のような直接値を比較することになる。
そのため、想定した値とは別の値で合致すると判断され、誤った値に置換されてしまった、
ということはないと思うが、
より頻出するであろう値を先に持ってくることで、処理時間の短縮につなげるといった工夫が可能である。
■③デフォルトの値を設定しなかった場合
デフォルトの値は、引数の最後で指定できるが、指定は任意である。
デフォルトの値を指定せず、他のどの値とも合致しなかった場合は、NULLが返される。
■④データ型
引数で指定できるデータ型は、以下に限られる。
・任意の数値型(NUMBER
、BINARY_FLOAT
、BINARY_DOUBLE
)
・文字列型
値の比較および最終結果値の返却は、
1番最初の「値A」と「値Aの置換後の値」のペアのデータ型に合わせて行われる。
データ型の補正について、詳細はOracleのドキュメント参照のこと。
3.参考:類似関数
最後に、DECODE関数と類似する関数を2つ紹介する。
■CASE関数
CASE関数は、DECODE関数と同じような置き換え処理ができる関数。
今回のテーマのDECODE関数は、演算式や、正規表現の利用といった、柔軟な値設定ができない。
Aという値がきたらA´という値を返す、Bという値が来たらB´という値を返す…、というように、
返す値を直接指定して変えるのみである。
対してCASE関数では、返す値を演算によって導くという、より高度なことができる。
また一般的なプログラミング言語でも、よくCASE式による条件分岐処理はお目にかかることから、
DECODE関数よりも、何をしている処理なのかが直感的に分かりやすい。
そのため、CASE関数のほうが、DECODE関数よりも好まれる傾向にある。
CASE関数の詳細は、次回以降の記事で別途まとめる予定。
■NVL関数
前回の記事で扱ったNVL関数も、返却値の置き換えという意味で、DECODE関数に似た側面を持つ。
(前回の記事はこちら)
NVL関数は、引数は「列名」と「置き換え後の値」の2つである。
置き換えは、列の値がNULLの場合に行われることが決まっており、
NULL以外なら列の値をそのまま返却する仕組みとなっている。
NVL関数では、値がNULLかどうかという、シンプルな条件分岐が実現できるため、
単に値がNULLの場合に置き換えをしたいなら、DECODE関数よりもNVL関数を選ぶと良い。
■まとめると…
以下のような使い分けができそうである。
・CASE関数→複雑な条件分岐によって置換したい、拡張性を持たせておきたい
・NVL関数→NULLの時だけ置換したい
・DECODE関数→取得される列の値が限定的であり、拡張の必要性もない
ということで、DECODE関数について調べた結果、
あんまり使う機会はなさそうということが分かった…(;^ω^)
今回は以上!