Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram illustrating the syntax and usage of the LIKE keyword within a standard SOQL query structure.
Apex

SOQL LIKE and NOT LIKE: Wildcards, Syntax and Apex Examples

SOQL has no NOT LIKE operator. Write (NOT Name LIKE '%x%') instead. This guide covers % and _ wildcards, escaping, binding Apex variables and lists, and which field types LIKE accepts.

The short answer

There is no NOT LIKE operator in SOQL. Negate the condition in parentheses: WHERE (NOT Name LIKE '%test%'). LIKE itself takes two wildcards, % for any run of characters and _ for exactly one, and it ignores case.

Key takeaways SOQL has no NOT LIKE. Write (NOT Name LIKE '%x%'). The form Name NOT LIKE '%x%' is a parse error. % matches any run of characters and _ matches exactly one. LIKE without a wildcard is a case-insensitive exact match. Add the wildcards to the Apex variable before you bind it. You can also bind a List to match any pattern in the list. LIKE fails on ID, number and multi-select picklist fields, and Long Text Area fields cannot be filtered at all. A leading % cannot use an index. Anchor the pattern at the start on large objects.

LIKE filters on part of a text field: names that contain a word, codes that start with a prefix, or text that sits between two known words. The part people get stuck on is the negative form. SOQL has no NOT LIKE operator, so you negate the whole condition instead:

List<Account> accounts = [
  SELECT Id, Name FROM Account
  WHERE (NOT Name LIKE '%test%')
];

Everything below was run against a live org. The errors quoted are the ones Salesforce returned.

NOT LIKE: the syntax that works

Put NOT before the field and wrap the condition in parentheses.

// Works
WHERE (NOT Name LIKE '%test%')

// Parse error: SOQL has no NOT LIKE operator
WHERE Name NOT LIKE '%test%'

The parentheses matter as soon as you combine conditions. WHERE (NOT Name LIKE '%test%') AND Type = 'Customer' is unambiguous. Without the parentheses you are relying on operator precedence, and the query is harder to read.

To exclude several patterns, negate each one or negate a list bind (covered below):

WHERE (NOT Name LIKE '%test%') AND (NOT Name LIKE '%demo%')

NOT LIKE keeps blank values

A negated LIKE returns rows where the field is null. In the test org, 6 of 8 accounts had no website, and (NOT Website LIKE '%zzqq%') returned all 8. SQL would have dropped the blanks. If you only want rows that have a value, add AND Website != null. SOQL does not accept IS NOT NULL.

The two wildcards

Pattern Matches
'Acme%' starts with Acme
'%Acme' ends with Acme
'%Acme%' contains Acme anywhere
'Acme%Ltd' starts with Acme and ends with Ltd
'J_n' Jan, Jen, Jon (exactly one character in the middle)
'Acme' exactly Acme, ignoring case

LIKE ignores case. '%a%' and '%A%' returned the same 7 accounts in the test org. There is no case-sensitive option, so filter in Apex when case matters.

Matching text between two words

Put % between the words, and on both ends if they can sit anywhere in the field:

List<Account> accounts = [
  SELECT Id, Name, Industry FROM Account
  WHERE Industry LIKE '%Technology%Services%'
];

That matches "Technology Services", "Technology and Services" and "Technology, Consulting Services". It does not match "Services in Technology", because the order of the words matters.

Use _ when exactly one character must sit between them. '%Street_Avenue%' matches "Street Avenue" but not "Street Avenue" with two spaces.

Binding Apex variables

A bind variable is used as the full pattern, so add the wildcards in Apex first:

String keyword = '%' + searchTerm + '%';
List<Account> accounts = [
  SELECT Id, Name FROM Account WHERE Name LIKE :keyword
];

// Negated
List<Account> others = [
  SELECT Id, Name FROM Account WHERE (NOT Name LIKE :keyword)
];

Binding :searchTerm without the % gives you an exact match, which is the usual reason a search box "finds nothing".

Binding a list of patterns

You can bind a List<String>, and SOQL returns records that match any pattern in it:

List<String> patterns = new List<String>{ '%Acme%', 'Global%', '%Ltd' };
List<Account> accounts = [
  SELECT Id, Name FROM Account WHERE Name LIKE :patterns
];

This works the same as an OR of three LIKE conditions and keeps the query readable when the list comes from configuration.

Escaping % and _

A % or _ typed by a user acts as a wildcard. To match it literally, escape it with a backslash in the SOQL text:

SELECT Id FROM Product2 WHERE Name LIKE '50\% off'

When you build that query as an Apex string, the backslash needs escaping too, so it reaches SOQL intact:

String soql = 'SELECT Id FROM Product2 WHERE Name LIKE \'50\\% off\'';
List<Product2> products = Database.query(soql);

For dynamic SOQL built from user input, also run the input through String.escapeSingleQuotes() so a stray quote cannot change the query.

Which field types accept LIKE

Field type LIKE works? What happens instead
Text, Text Area (255) Yes
Email, Phone, URL Yes
Picklist (single-select) Yes Industry LIKE 'Tech%' works
ID No invalid operator on id field
Number, Currency, Date No like operator only valid on string field
Multi-select picklist No invalid operator on multipicklist field. Use INCLUDES
Long Text Area, Rich Text No the field can not be filtered in query call. Use SOSL

For a multi-select picklist, see SOQL CONTAINS vs LIKE vs INCLUDES.

Performance

An index can only help when the pattern is anchored at the start. 'Acme%' can use an index on Name. '%Acme%' cannot, so on an object with hundreds of thousands of rows the optimizer has to scan, and in a trigger that can end in a non-selective query error.

  • Anchor the pattern at the start when the business rule allows it.
  • Add a selective filter, such as a date range or an owner, alongside the LIKE.
  • For free-text search across fields or objects, use SOSL FIND, which runs on Salesforce's search index.

Common mistakes

  • Writing Name NOT LIKE. Use (NOT Name LIKE ...).
  • Binding a variable without wildcards and getting an exact match.
  • Expecting NOT LIKE to drop blank values. It keeps them. Add AND field != null.
  • Using LIKE on an ID, a number or a multi-select picklist.
  • Starting every pattern with % on a large object.
Free tool SOQL Query Builder Build SOQL queries visually, browse objects and fields from your live Salesforce org.

Frequently asked questions

How do I write NOT LIKE in SOQL?

SOQL has no NOT LIKE operator. Put NOT in front of the whole condition and wrap it in parentheses: SELECT Id, Name FROM Account WHERE (NOT Name LIKE '%test%'). Writing Name NOT LIKE '%test%' is a parse error. The negated form also returns rows where the field is blank.

What is the SOQL LIKE operator?

LIKE matches part of a text value. % matches any number of characters, including none, and _ matches exactly one. WHERE Name LIKE '%Acme%' returns every record whose Name contains Acme.

Is SOQL LIKE case-sensitive?

No. LIKE ignores case, so WHERE Name LIKE '%acme%' matches Acme, ACME and acme. There is no case-sensitive option. If you need one, filter the results in Apex with String.equals() or String.contains().

What wildcards does SOQL LIKE support?

Two: % for zero or more characters and _ for exactly one character. There are no character classes or regular expressions. For anything more complex, query broadly and filter in Apex with a Pattern.

How do I match a literal % or _ in SOQL LIKE?

Escape it with a backslash in the SOQL text, so the pattern for the literal text 50% off is a backslash before the %. When you build the query as an Apex string, double the backslash so it reaches SOQL. When the pattern comes from user input, escape quotes with String.escapeSingleQuotes() as well.

Which field types support SOQL LIKE?

LIKE works on text-based fields such as Text, Text Area, Email, Phone, URL and single-select Picklist. It fails on ID fields (invalid operator on id field), numbers (like operator only valid on string field), multi-select picklists (use INCLUDES) and Long Text Area fields, which cannot be filtered at all.

Why is my SOQL LIKE query slow?

A pattern that starts with %, such as '%Acme%', cannot use an index, so on a large object the optimizer has to scan. Anchor the pattern at the start ('Acme%') where you can, add another selective filter, or switch to SOSL for free-text search.

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