T-SQL - CHOOSE 関数の使い方:インデックスで値を取得する方法

CHOOSE 関数の使い方:インデックスで値を取得する方法

今回は、配列からインデックスを指定して値を取得するような動きをする、CHOOSE 関数についてご紹介します。

CHOOSE 関数の基本的な使い方と注意点

SQL Server の CHOOSE 関数は、引数として渡した値のリストから、インデックスで指定した値を返す関数です。

SQL Server 2012 以降で使用できます。


CHOOSE 関数の基本構文は以下の通りです。

CHOOSE ( インデックス, 値1, 値2, ... [, 値n ] )  

[インデックス] には、どのインデックスの値を取得するかを整数で指定します。

インデックスは 1 始まりなのでご注意ください。

0 や、続いて渡すリストの値の数より大きいインデックスを指定すると、エラーにはなりませんが、戻り値は NULL になります。


値1, 値2, ... [, 値n ] には、CHOOSE 関数を使って取得したい値のリストを渡します。

入力引数の値のデータ型は、それぞれなんでも大丈夫ですが、戻り値のデータ型はその中で一番高い優先順位のデータ型になるので注意必要です。(後述します)


それでは、CHOOSE 関数の動きを簡単な例で確認してみます。

'A', 'B', 'C', 'D', 'E' の文字列のリストの中から、CHOOSE 関数を使ってインデックスを指定して値を取得するには次のようにできます。

SELECT  CHOOSE(0, 'A', 'B', 'C', 'D', 'E') AS Value0,
        CHOOSE(1, 'A', 'B', 'C', 'D', 'E') AS Value1,
        CHOOSE(2, 'A', 'B', 'C', 'D', 'E') AS Value2,
        CHOOSE(3, 'A', 'B', 'C', 'D', 'E') AS Value3,
        CHOOSE(4, 'A', 'B', 'C', 'D', 'E') AS Value4,
        CHOOSE(5, 'A', 'B', 'C', 'D', 'E') AS Value5,
        CHOOSE(6, 'A', 'B', 'C', 'D', 'E') AS Value6;

[実行結果]
CHOOSE 関数の使い方 1

インデックスが 0 の時や、リストの値の数を超えた 6 の時には NULL が、それ以外の時には、それぞれインデックスで指定した値が返ってきていますね。


CHOOSE 関数へ入力引数として渡す値に、いろんなデータ型のものを混ぜてみます。

SELECT CHOOSE(1, 'a', 0.999, GETDATE());

これを実行すると、インデックス 1 の 'a' を一番優先順位の高い DATETIME 型に変換しようとし、次のようなエラーになってしまいます。

[実行結果]
CHOOSE 関数の使い方 2

Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.

SELECT CHOOSE(2, 'a', 0.999, GETDATE());

これを実行すると、インデックス 2 の 0.999 が一番優先順位の高い DATETIME 型に変換され、1900-01-01 23:58:33.600 という予期せぬ値が戻り値として返ってきています。

[実行結果]
CHOOSE 関数の使い方 3


このように、入力引数に渡す値はデータ型が違っても指定できますが、戻り値が一番優先順位の高いデータ型に変換されるので、エラーや予期せぬ結果になることがあります。

ですので、CHOOSE 関数へ入力引数として渡す値には、同じデータ型の値を指定することをおすすめします。


CHOOSE 関数について思うこと

これは私が CHOOSE 関数について個人的に思うことなのですが、インデックスを指定して決まった値をハードコードして取得するような状況があるのであれば、できるだけ、そのインデックスを ID として、マスター化してテーブルを持ち、そのテーブルと結合することで値を取得したほうがいいと思っています。

そのインデックスを使って値を取るために、クエリーを書くたびに値をハードコードしなくてはならず、また、リストの値が増えた時や、値が変更になった時などには、そのハードコードした箇所を探して全箇所変更しなければならなくなるからです。

ですので、CHOOSE 関数はあんまり使う機会がないかもしれません。

使ってもいいかな?と思える場面は、値の数が少なく、値も固定で変更になることは決してなく、あちらこちらでそのインデックスを値に変換するクエリーを書くことがないようなケースかなと思います。


私が思う CHOOSE 関数が使えそうな状況は、上の条件を満たしていて、かつ CASE 式でインデックスの値によって、この時はこの値、のように書きたいような時です。

例えば、「DATEPART 関数を使って日本語の曜日を取得する」の記事で、DATEPART 関数 と CASE 式を使って、日付から日本語の曜日を取得する方法をご紹介しました

以下のようなクエリーをつかって取得しました。詳細については「DATEPART 関数を使って日本語の曜日を取得する」をご覧ください。

--SET DATEFIRST 7;

DECLARE @Date1 DATE = '2025-07-25';

SELECT  CASE DATEPART(WEEKDAY, @Date1)
          WHEN 1 THEN N'日'
          WHEN 2 THEN N'月'
          WHEN 3 THEN N'火'
          WHEN 4 THEN N'水'
          WHEN 5 THEN N'木'
          WHEN 6 THEN N'金'
          WHEN 7 THEN N'土'
        END AS DayOfWeek_JP;

[実行結果]
CHOOSE 関数の使い方 4


これを CHOOSE 関数を使って書き直すと次のようになります。

--SET DATEFIRST 7;

DECLARE @Date1 DATE = '2025-07-25';

SELECT CHOOSE(DATEPART(WEEKDAY, @Date1), N'日', N'月', N'火', N'水', N'木', N'金', N'土') AS DayOfWeek_JP;

[実行結果]
CHOOSE 関数の使い方 5

同じ結果が得られていますし、CHOOSE 関数を使ったほうがシンプルですね。


以上、配列からインデックスを指定して値を取得するような動きをする、CHOOSE 関数についてご紹介しました。

© 2010-2025 SQL Server 入門