Apex

複数選択リストをINCLUDES・EXCLUDESで検索する書き方

複数選択リストは通常の等号では正しく検索できません。INCLUDES・EXCLUDESという専用の演算子と、値の上限を知っておく必要があります。

2025.07.17

なぜ専用の演算子が要るのか

複数選択リストは、1つの項目に複数の値をまとめて保持します。データの実体は、選択された値をセミコロンでつないだ1本の文字列です。

WHERE MultiSelect__c = 'A' と書いても、値が 'A;B' のレコードは一致しません。文字列全体が一致するかどうかしか見ないからです。複数選択リストの中の1つの値を探すには、専用の演算子が要ります。

複数選択リスト項目を用意する

検証用に、取引先へカスタムの複数選択リスト項目を作ります。

  1. オブジェクトマネージャを開く

    設定から取引先オブジェクトを選び、項目とリレーションを開きます。

  2. 新規項目を作成する

    データ型で「選択リスト(複数選択)」を選びます。

  3. 選択肢と表示行数を決める

    値を1行ずつ入力します。ここでは検証用にA・B・C・Dの4つを登録します。

  4. ページレイアウトに配置して保存する

    取引先の主要なページレイアウトに項目を追加します。

複数選択リスト項目の定義画面。データ型が選択リスト(複数選択)
複数選択リスト項目の定義。SOQLで使うのは、表示ラベルではなくAPI参照名のほうです。
選択リスト値の一覧画面。値とAPI参照名がA・B・C・Dで並んでいる
登録した選択肢。INCLUDESに書くのは、この一覧のAPI参照名です。

検証用のレコードを作る

取引先を3件作り、複数選択リストの値を次のように選びます。

取引先名選択した値保存される文字列
test1AA
test2BB
test3A、BA;B
取引先test1の詳細。複数選択にAが入っている
test1の詳細。値を1つだけ選んだ状態です。
取引先test2の詳細。複数選択にBが入っている
test2の詳細。別の値を1つだけ選んでいます。
取引先test3の詳細。複数選択にA; Bが入っている
test3の詳細。2つ選ぶと、画面では区切って表示されます。保存されている文字列はセミコロン区切りです。

画面の選択リストでは、Ctrlキー(macOSはCommandキー)を押しながらクリックすると複数選択できます。

INCLUDESとEXCLUDESの構文

複数選択リストで使える演算子は次の4つです。

演算子意味
=選択されている値の組み合わせが完全に一致する
!=完全には一致しない
INCLUDES指定した値のどれかを含む
EXCLUDES指定した値をどれも含まない
SELECT Id, Name FROM Account WHERE MultiSelect__c = 'A'

完全一致は組み合わせごと一致します。A;Bの取引先はヒットしません。

SELECT Id, Name FROM Account WHERE MultiSelect__c INCLUDES ('A','B')

INCLUDESは丸カッコの中に候補をカンマで並べます。どれか1つでも含めば一致します。

セミコロンは、1件のレコードの中で複数の値を区切るための記号です。検索条件の側でセミコロンをつなげて 'A;B' と書くと、AとBの両方が選ばれているレコードだけを探す意味になります。片方だけ選ばれているレコードも拾いたいときは、カンマ区切りのINCLUDESを使います。

LIKEは使えない

LIKE は文字列項目専用の演算子で、複数選択リストには使えません。部分一致で探したいときも、INCLUDES・EXCLUDESに候補を並べる形で書きます。

値の上限を知っておく

項目上限
カスタム複数選択リストの選択肢の数500
1件のレコードで同時に選べる値の数100
選択肢1つあたりの文字数255

複数選択リストには、上限以外にも押さえておきたい制約があります。レポートのスナップショットでは複数選択リストをそのまま使えません。値ごとに INCLUDES を使った数式項目へ分解してからマッピングします。

Apexで動的に検索する

検索したい値を実行時に組み立てる場合は、文字列をそのままつなぎません。String.escapeSingleQuotes() でエスケープしてから、動的SOQLに渡します。

List<String> values = new List<String>{ 'A', 'B' };
List<String> quoted = new List<String>();
for (String value : values) {
  quoted.add('\'' + String.escapeSingleQuotes(value) + '\'');
}

String soql = 'SELECT Id, Name, MultiSelect__c FROM Account';
if (!quoted.isEmpty()) {
  soql += ' WHERE MultiSelect__c INCLUDES (' + String.join(quoted, ',') + ')';
}
soql += ' LIMIT 200';

List<Account> accounts = Database.query(soql);

選択した値のリストからINCLUDES句を安全に組み立てます。空リストのときは条件を付けません。

動的に値を組み立てるときは、上のようにエスケープした文字列を自分で並べます。

ここで間違えやすい

間違い何が起きるか
LIKE を使う複数選択リストには使えません。コンパイルが通りません
値をエスケープせずに連結するシングルクォートを含む値でSOQLインジェクションの危険があります
= で1つの値だけを探す他の値と組み合わせて選ばれているレコードを取りこぼします
INCLUDESの候補にセミコロンを使う「両方選ばれている」条件に変わり、意味が変わります
レポートスナップショットにそのまま載せようとする複数選択リストは使えません。値ごとの数式項目に分解します

確認した環境

  • 2026年9月/Salesforce Summer '26(APIバージョン67.0)時点の公式リファレンスで、演算子の構文と値の上限を確認しています

まとめ

  • 複数選択リストは、選択された値をセミコロンでつないだ1本の文字列として保存されます
  • 検索には INCLUDES・EXCLUDES を使います。LIKE は使えません
  • INCLUDESの丸カッコの中はカンマ区切りです。セミコロンでつなぐと「両方選ばれている」という意味に変わります
  • カスタム複数選択リストは500値まで、1レコードで同時に選べるのは100値まで、1値は255文字までです
  • レポートのスナップショットには使えません。値ごとの数式項目に分解します
  • 動的に値を組み立てるときは String.escapeSingleQuotes() でエスケープしてから並べます

Salesforceの導入・運用についてご相談ください

導入前の検討から、お使いの環境の改修・運用、AIとの連携まで承ります。状況を伺ったうえで、進め方をご提案します。