Understanding SOQL joins is essential for mastering Salesforce development. Whether you’re building Apex logic, writing data-heavy reports, or optimizing queries for performance, knowing how to navigate parent-to-child and child-to-parent relationships in SOQL can save time and governor limits — and massively level up your Salesforce skills.
In this guide, we’ll explore everything you need to know about SOQL relationships, from syntax and examples to performance tips and use cases.
SOQL (Salesforce Object Query Language) lets you query records from standard and custom objects. But real power comes when you can query related records using relationship queries — a.k.a. joins in SOQL.
Instead of writing multiple queries and stitching data together in Apex, you can:
Before we dive into queries, it’s key to understand how relationships in Salesforce work:
These relationships enable child-to-parent and parent-to-child traversals in SOQL.
This is the most common form of SOQL join. You retrieve fields from a parent object while querying a child object.
SELECT Name, Account.Name, Account.IndustryFROM ContactWHERE Account.Industry = 'Technology'
Contact
Account
recordSELECT Name, Account.Name, Account.AnnualRevenueFROM ContactWHERE Account.AnnualRevenue > 1000000
Use this when you want child records (Contacts) but also need details from their associated parent (Account).
These are less commonly used but extremely powerful. Instead of dot notation, you use subqueries to retrieve related child records from a parent.
SELECT Name, (SELECT LastName FROM Contacts)FROM AccountWHERE Industry = 'Finance'
Account
Contact
recordsSELECT Name, Custom_Parent__r.NameFROM Custom_Child__c
__r
(relationship suffix for custom objects)SELECT Name, (SELECT Name FROM Custom_Children__r)FROM Custom_Parent__c
Always reference the child relationship name with __r
.
You can chain relationships across multiple levels.
SELECT Name, Account.Name, Account.Parent.NameFROM ContactWHERE Account.Parent.Name != null
Or do nested subqueries:
SELECT Name, (SELECT Subject FROM Cases),(SELECT LastName FROM Contacts)FROM Account
Instead of writing multiple SOQL statements, join records in a single call.
For custom objects, use __r
and reference child relationship names carefully.
When dealing with child-to-parent, you can map results for faster processing in Apex.
Map<Id, Account> accountsMap = new Map<Id, Account>([SELECT Id, Name, (SELECT Name FROM Contacts) FROM Account WHERE Industry = 'Technology']);
Avoid deeply nested queries as they can become hard to debug and hit limits.
SOQL joins are essential for writing efficient, readable, and scalable queries in Salesforce. By mastering both child-to-parent and parent-to-child relationship queries, you’ll be able to drastically reduce your query count, simplify your Apex logic, and become a more effective Salesforce developer.
Got stuck on a relationship name? Drop a comment or explore our SOQL Cheat Sheet for Developers to fast-track your Salesforce querying skills!
Quick Links
Legal Stuff