Skip to main content

Apex

SOQL Tutorial: Salesforce Object Query Language Explained

SOQL is how Apex (and much of Salesforce) reads data. Here's a practical walkthrough — from basic queries to relationship queries and common pitfalls.

26 February 2026·7 min read

SOQL (Salesforce Object Query Language) is how Apex code — and much of the platform itself — reads data from the database. If you're learning Salesforce development, fluency in SOQL is non-negotiable.

Basic Query Syntax

SELECT Id, Name, Industry
FROM Account
WHERE Industry = 'Technology'
ORDER BY Name ASC
LIMIT 50

Unlike SQL, there's no SELECT * — you must explicitly list every field you want back. This keeps queries intentional and avoids pulling unnecessary data.

Relationship Queries

Child-to-Parent (dot notation)

SELECT Id, Name, Account.Industry, Account.Owner.Name
FROM Contact
WHERE Account.Industry = 'Technology'

You can traverse up to 5 levels of parent relationships using dot notation.

Parent-to-Child (subquery)

SELECT Id, Name, (SELECT Id, LastName FROM Contacts)
FROM Account
WHERE Industry = 'Technology'

This returns each Account along with a nested list of its related Contacts — accessed in Apex as a list within each parent record.

Aggregate Queries

SELECT Industry, COUNT(Id) accountCount
FROM Account
GROUP BY Industry

Aggregate functions (COUNT, SUM, AVG, MIN, MAX) combined with GROUP BY let you summarize data directly in the query, rather than pulling records and looping through them in Apex.

SOSL: Searching Across Objects

FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, Name)

SOSL is the right tool when you don't know which object contains a match — like a global search bar — rather than SOQL, which requires you to already know which object you're querying.

Common Mistakes (and Governor Limit Impact)

1. SOQL inside a loop. This is the #1 mistake:

// Bad: one query per loop iteration
for (Contact c : contactList) {
    Account a = [SELECT Id, Name FROM Account WHERE Id = :c.AccountId];
}

Fix by querying once, outside the loop, using a Set of IDs:

Set<Id> accountIds = new Set<Id>();
for (Contact c : contactList) accountIds.add(c.AccountId);
Map<Id, Account> accounts = new Map<Id, Account>(
    [SELECT Id, Name FROM Account WHERE Id IN :accountIds]
);

2. Querying fields you don't need. Every extra field adds to the response payload and heap usage — query only what you'll actually use.

3. Not using selective filters on large objects. Unselective queries on objects with millions of records can time out or be skipped by the query optimizer — always filter on indexed fields where possible.

4. Forgetting security enforcement. By default, SOQL in Apex runs in system context and ignores field-level security and sharing unless you explicitly use WITH SECURITY_ENFORCED, WITH USER_MODE, or run the encapsulating class with sharing — a common oversight with real security implications.

Practicing SOQL

The best way to build fluency is writing real queries against a real data model — not just reading syntax. Our Salesforce Developer Training course includes hands-on SOQL practice as part of the Apex fundamentals module.

Frequently Asked Questions

SOQL queries a single object (and its related objects) with precise conditions — think SQL's SELECT. SOSL searches across multiple objects at once for a text term — better for global search-style use cases where you don't know which object contains the match.

Ready to start your Salesforce career?

Enquire now and our team will help you find the right batch.

Enquire Now