【SQL】DECODE関数 | 若手エンジニアのブログ

若手エンジニアのブログ

文系出身の若手女子エンジニアによる技術ブログ。
日々の経験や学びをアウトプットするためにブログを書いています。
バックエンド(Java+SpringFramework)を経てインフラエンジニアになりました。
今は育休中につき、本で勉強したことを中心にアウトプットしています。

先日からSQLの記事を書いていますが、今回も同じくSQLの記事です。

環境はOracle19c。

 

もくじ

1.DECODE関数とは

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が返される。

 

■④データ型

引数で指定できるデータ型は、以下に限られる。

 ・任意の数値型(NUMBERBINARY_FLOATBINARY_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関数について調べた結果、

あんまり使う機会はなさそうということが分かった…(;^ω^)

 

 

今回は以上!