Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Apex

SOQL CONTAINS vs LIKE vs INCLUDES: When to Use Each Operator

SOQL has no CONTAINS keyword. Most queries reaching for one want LIKE with wildcards, or INCLUDES for a multi-select picklist. Pick by field type.

The short answer

SOQL has no CONTAINS keyword. Use LIKE with % wildcards to find a substring in a text field, INCLUDES for a multi-select picklist, and SOSL FIND when the search spans several fields or several objects.

Key takeaways LIKE is the closest thing SOQL has to CONTAINS. % matches zero or more characters, _ matches exactly one, and omitting the wildcards leaves you with an exact match. A leading % defeats the index optimizer, so anchor the pattern at the start or switch to SOSL on large data volumes. Multi-select picklists need INCLUDES, not LIKE. Salesforce stores their values as semicolon-separated strings whose order is not guaranteed, so partial matches collide. In INCLUDES, 'VIP;Enterprise' as a single string means both values must be present, while 'VIP', 'Enterprise' as two strings means either one matches.

A surprising number of "SOQL contains" questions on the Trailblazer Community come down to picking the wrong operator for the field type. SOQL has no CONTAINS keyword at all, and the three operators that do express containment behave very differently.

The decision rule

Your field is... Your goal is... Use
Text (String, Email, URL, TextArea) Find rows where the field has a substring LIKE '%substring%'
Multi-select picklist Find rows where the field includes one or more values INCLUDES('Value1;Value2')
Anything Free-text search across many fields/objects SOSL FIND {term} IN ALL FIELDS
Long Text Area, Rich Text Substring search LIKE works but is slow, so prefer SOSL
Number, Date, Boolean "Contains" doesn't apply Use =, >=, IN, BETWEEN

LIKE: substring matching for text fields

LIKE is the closest thing SOQL has to a CONTAINS operator. The % wildcard matches zero or more characters; the _ wildcard matches exactly one:

// Substring (CONTAINS-equivalent)
SELECT Id, Name FROM Account WHERE Name LIKE '%consulting%'

// Starts with
SELECT Id, Name FROM Account WHERE Name LIKE 'Acme%'

// Ends with
SELECT Id, Name FROM Account WHERE Name LIKE '%Inc.'

// Single-character wildcard
SELECT Id FROM Lead WHERE FirstName LIKE 'J_n'  // matches Jan, Jon, Jen

Note: a leading % (like '%consulting%') defeats Salesforce's index optimizer, so the query plan has to scan more rows. For LDV scenarios, anchor at the start ('consulting%') or use SOSL.

INCLUDES: the multi-select picklist operator

Multi-select picklists are the one place LIKE doesn't reliably work. Salesforce stores their values as semicolon-separated strings internally, but the order isn't guaranteed and partial matches can collide with longer values. Always use INCLUDES:

// Find Accounts tagged VIP — works regardless of where VIP appears in the list
SELECT Id, Name FROM Account WHERE Tags__c INCLUDES ('VIP')

// Multiple values: AND semantics within parens (must include both)
SELECT Id, Name FROM Account WHERE Tags__c INCLUDES ('VIP;Enterprise')

// OR semantics: separate quoted strings
SELECT Id, Name FROM Account WHERE Tags__c INCLUDES ('VIP', 'Enterprise')

// Inverse — does NOT contain
SELECT Id, Name FROM Account WHERE Tags__c EXCLUDES ('VIP')

The combination 'VIP;Enterprise' (semicolon, single string) means "must contain BOTH VIP and Enterprise." Splitting them as 'VIP', 'Enterprise' (two separate strings) means "contains either VIP OR Enterprise." This is the most-missed nuance of INCLUDES.

If your "contains" question spans multiple fields or multiple objects (e.g., a global search bar that searches accounts, contacts, AND opportunities), use SOSL. It's purpose-built for this, and Salesforce maintains a separate full-text index:

List<List<SObject>> results = [
  FIND {acme corp}
  IN ALL FIELDS
  RETURNING
    Account(Id, Name),
    Contact(Id, FirstName, LastName, Email),
    Opportunity(Id, Name, StageName)
  LIMIT 50
];

List<Account> accounts = (List<Account>) results[0];
List<Contact> contacts = (List<Contact>) results[1];

A SOSL statement chains in order: the typed search term, then an optional IN [field group], then the typed return clauses, one per object. Each return list keeps the order you specified.

The "I want CONTAINS" decision tree

  1. Searching one text field for a substring? LIKE '%term%'.
  2. Searching a multi-select picklist for a value? INCLUDES('value').
  3. Searching multiple fields or multiple objects? SOSL FIND.
  4. Searching a Long Text Area? SOSL is faster.
  5. Is the field a Number, Date, or Boolean? "Contains" doesn't apply; use the appropriate comparison.

Common mistakes

  • Using LIKE on multi-select picklists. Will work some of the time, fail unpredictably the rest. Always INCLUDES.
  • Forgetting wildcards on LIKE. WHERE Name LIKE 'consulting' is exact-match, not substring. You must include %.
  • Leading wildcard on a non-indexed field at LDV. Tanks performance. Switch to SOSL or restructure the query.
  • Swapping the AND and OR semantics in INCLUDES. INCLUDES('A;B') is AND; INCLUDES('A', 'B') is OR. Easy to get backwards.

CONTAINS isn't a SOQL keyword, and you almost never need it. LIKE handles substring search, INCLUDES handles multi-selects, and SOSL handles everything else.

Frequently asked questions

Is there a CONTAINS keyword in SOQL?

No. SOQL has no CONTAINS operator. For a substring search on a text field, use LIKE with % wildcards: WHERE Name LIKE '%foo%'. To check values in a multi-select picklist, use INCLUDES('Value1;Value2'). For full-text search across many fields and objects, use SOSL with FIND {searchTerm}.

How do I check if a SOQL field contains a substring?

Use LIKE with both a leading and a trailing % wildcard: SELECT Id FROM Account WHERE Name LIKE '%bank%'. The % matches zero or more characters. For 'starts with' use 'bank%', and for 'ends with' use '%bank'. LIKE ignores case, so 'BANK' matches 'bank'.

What is the SOQL INCLUDES operator?

INCLUDES checks whether a multi-select picklist field holds specific values: SELECT Id FROM Account WHERE Tags__c INCLUDES ('VIP;Enterprise'). Values are combined with a semicolon. EXCLUDES does the inverse. INCLUDES is the only reliable way to query a multi-select picklist, since LIKE does not work dependably on them.

Can SOQL do full-text search across multiple fields?

Not with SOQL alone. Use SOSL instead: FIND {acme} IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, FirstName, LastName). SOSL is purpose-built for cross-object, cross-field text search and is much faster than chaining many LIKE clauses with OR.

What's the difference between LIKE and INCLUDES in SOQL?

LIKE searches text fields (String, Email, URL, etc.) using wildcards. INCLUDES searches multi-select picklists for specific values, semicolon-separated. They operate on different field types and are not interchangeable: LIKE on a multi-select picklist often misses values that aren't first in the list.

Why doesn't LIKE work on my multi-select picklist?

Multi-select picklists store values internally as semicolon-separated text, but LIKE matching is unreliable: the order of values isn't guaranteed, and partial-match patterns collide with similar values (e.g., LIKE '%New%' matches both 'New' and 'NewYork'). INCLUDES guarantees an exact value match within the picklist.

Is SOQL LIKE case-sensitive?

No. LIKE is always case-insensitive. WHERE Name LIKE 'apple' matches Apple, APPLE, and aPpLe. There is no case-sensitive variant. If you need a case-sensitive comparison, do it in Apex after the query: if (account.Name.equals('apple')) { ... }.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment