Salesforce Object Query Language (SOQL) is used to read records from Salesforce objects. SOQL syntax looks similar to SQL, but it is built for Salesforce object API names, field API names, and object relationships. In Apex, a SOQL query is usually written inline inside square brackets.
This updated tutorial explains the required parts of Apex SOQL syntax, the optional clauses used most often, and practical examples for WHERE, IN, bind variables, sorting, limits, and relationship queries.
SOQL Syntax
SELECT fields
FROM Object
WHERE Condition
Ordering LIMIT
FOR VIEW Or FOR REFERENCE
OFFSET
UPDATE VIEWSTAT
From the above SOQL syntax we have many things to observe and understand. SELECT, fields, FROM, and Object are required in a normal SOQL query. Clauses such as WHERE, ORDER BY, LIMIT, OFFSET, FOR VIEW, and FOR REFERENCE are optional and are added only when the query needs them.
Apex SOQL syntax keywords and what each part does
| SOQL part | Description |
|---|---|
SELECT | Lists the fields to retrieve from each record. |
fields | Field API names such as Id, Name, Phone, or CreatedDate. SOQL does not use SELECT *. |
FROM | Specifies the Salesforce object being queried. |
Object | Standard or custom object API name, for example Account, Contact, or Invoice__c. |
WHERE | Filters records by one or more conditions. |
ORDER BY | Sorts returned rows in ascending or descending order. |
LIMIT | Restricts the number of rows returned. |
OFFSET | Skips rows before returning results, usually for simple paging. |
FOR VIEW | Updates the LastViewedDate value for returned records. |
FOR REFERENCE | Updates the LastReferencedDate value for returned records. |
UPDATE VIEWSTAT | Used only for supported Salesforce Knowledge article view-stat use cases. |
The API names of the fields are used in the SELECT statement. Use the field API name, not the field label shown to users. Custom fields end with __c, and custom relationship names often end with __r.
Basic SELECT and FROM syntax for Salesforce records
The simplest SOQL query names the fields after SELECT and the object after FROM. This query returns account names and phone numbers.
SELECT Name, Phone
FROM Account
In the Developer Console Query Editor, run only the SOQL statement. In Apex, wrap the SOQL statement in square brackets and assign the result to a list of sObjects.
List<Account> accounts = [
SELECT Name, Phone
FROM Account
];
If Apex code needs to read a field, include that field in the SELECT clause. Otherwise, the record returned by SOQL may not contain the field value you try to access.
Filtering Apex SOQL records with WHERE conditions
The WHERE clause filters records before they are returned. You can compare values, check for nulls, match text patterns, and combine conditions with AND, OR, and parentheses.
SELECT Id, Name, BillingCity
FROM Account
WHERE BillingCity = 'Hyderabad'
SELECT Id, Name, NumberOfEmployees, BillingCity
FROM Account
WHERE NumberOfEmployees > 50
AND (BillingCity = 'Hyderabad' OR BillingCity = 'Bengaluru')
| Filter need | SOQL condition example |
|---|---|
| Exact match | Industry = 'Education' |
| Not equal | Status__c != 'Closed' |
| Greater than | Amount > 10000 |
| Text pattern | Name LIKE 'Acme%' |
| Value from a list | Id IN :accountIds |
| Not blank | Email != null |
SOQL bind variable syntax in Apex
A bind variable allows a SOQL query to use an Apex variable. Add a colon before the Apex variable name inside the query.
String cityName = 'Hyderabad';
List<Account> accounts = [
SELECT Id, Name, BillingCity
FROM Account
WHERE BillingCity = :cityName
];
The IN operator is commonly used with a Set or List. This is a standard bulk Apex pattern because one query can retrieve records for many IDs.
Set<Id> accountIds = new Set<Id>();
for (Account acct : Trigger.new) {
accountIds.add(acct.Id);
}
List<Contact> contacts = [
SELECT Id, FirstName, LastName, AccountId
FROM Contact
WHERE AccountId IN :accountIds
];
ORDER BY, LIMIT, and OFFSET in SOQL queries
Use ORDER BY when row order matters. This is especially important when using LIMIT or OFFSET, because unordered results should not be treated as predictable.
SELECT Id, Name, CreatedDate
FROM Account
WHERE BillingCity != null
ORDER BY CreatedDate DESC
LIMIT 10
SELECT Id, Name
FROM Account
ORDER BY Name ASC
LIMIT 20
OFFSET 20
When a query might return no rows, assign the result to a list first instead of a single sObject variable. A single-record assignment can throw an exception when no record is returned.
List<Account> latestAccounts = [
SELECT Id, Name
FROM Account
ORDER BY CreatedDate DESC
LIMIT 1
];
if (!latestAccounts.isEmpty()) {
Account latestAccount = latestAccounts[0];
}
SOQL relationship query syntax for parent and child records
SOQL does not use SQL-style joins. To read related Salesforce records, use relationship query syntax. A child-to-parent query uses dot notation. A parent-to-child query uses a nested SELECT with the child relationship name.
Child-to-parent SOQL syntax with Account.Name
SELECT Id, FirstName, LastName, Account.Name
FROM Contact
WHERE Account.Name != null
Parent-to-child SOQL syntax with Contacts
SELECT Id, Name,
(SELECT Id, FirstName, LastName FROM Contacts)
FROM Account
For custom relationships, check the child relationship name in Object Manager before writing the nested query.
COUNT and aggregate SOQL syntax in Apex
Use COUNT() when you need a number instead of full records.
Integer contactsWithEmail = [
SELECT COUNT()
FROM Contact
WHERE Email != null
];
For grouped results, use aggregate functions with GROUP BY. Apex receives grouped rows as AggregateResult records.
List<AggregateResult> results = [
SELECT Industry, COUNT(Id) totalAccounts
FROM Account
WHERE Industry != null
GROUP BY Industry
];
Common Apex SOQL syntax mistakes to avoid
- Using SQL-only syntax: SOQL does not support
SELECT *or SQL join syntax. - Using field labels: Query field API names such as
BillingCity, not user-facing labels. - Accessing fields not selected: Add every field your Apex logic reads.
- Writing SOQL in a loop: Collect IDs first and query once outside the loop.
- Relying on random row order: Add
ORDER BYwhen order matters. - Ignoring access requirements: Production Apex should handle sharing, object permissions, and field-level access intentionally.
QA checklist for Apex SOQL syntax examples
- Check that every object and field uses the correct API name.
- Verify that the query has a valid
SELECTandFROM. - Confirm that Apex inline SOQL examples use square brackets.
- Use bind variables instead of manual string concatenation where possible.
- Keep SOQL outside loops in trigger and batch examples.
- Add
ORDER BYbeforeLIMITwhen row order matters. - Test relationship queries with the correct parent or child relationship name.
Official references for Apex SOQL syntax
For deeper reference, compare your queries with Salesforce’s official material: Trailhead: Write SOQL Queries and the Salesforce Apex Developer Guide for SOQL.
In our upcoming Salesforce developer tutorials we will learn about various SOQL syntax topics, including condition expression syntax using the WHERE clause and field expression syntax. You can also continue with the Salesforce Developer Tutorial series.
Apex SOQL syntax FAQs
What is the basic SOQL syntax in Apex?
The basic syntax is SELECT fields FROM ObjectName WHERE conditions. In Apex, place the query inside square brackets, for example List<Account> accounts = [SELECT Id, Name FROM Account];.
Can I use SELECT * in SOQL?
No. SOQL does not use SELECT *. List the fields you need, such as SELECT Id, Name, Phone FROM Account. Explicit field names also make Apex code easier to review.
How does the IN operator work in Apex SOQL?
Use IN with a collection and a bind variable, such as WHERE AccountId IN :accountIds. This is useful when querying records related to many IDs.
How is SOQL different from SQL?
SOQL is Salesforce-specific. It uses object and field API names, does not support SQL-style joins, and reads related records through relationship query syntax.
Should SOQL be written inside an Apex loop?
No. Avoid SOQL inside loops because Apex has governor limits. Collect values in a set or list, run one query outside the loop, and process the returned records.
Apex SOQL syntax summary for beginners
In this Salesforce Developer Tutorial, we learned that Apex SOQL syntax starts with SELECT fields and FROM an object. Optional clauses such as WHERE, ORDER BY, LIMIT, and OFFSET make the query more precise. In Apex code, prefer bind variables, query outside loops, use correct API names, and retrieve only the fields your logic needs.
TutorialKart.com