Intermediate 25 min read

Parent Relationship Queries

By the end of this lesson, you'll be able to:

  • Query fields on a parent record using dot notation in SOQL
  • Traverse more than one relationship level in a single query
  • Explain why this avoids a separate query for the parent record

Prerequisites: "Sorting and Limiting Results"

Querying a parent's fields directly

List<Contact> contacts = [
    SELECT Id, LastName, Account.Name, Account.Industry
    FROM Contact
];

for (Contact con : contacts) {
    System.debug(con.LastName + ' works at ' + con.Account.Name);
}
  1. List<Contact> contacts = [ — opens the query.
  2. SELECT Id, LastName, Account.Name, Account.Industry — this is Module 18's "Relationships in Apex" lesson from the query side: Account.Name and Account.Industry pull the parent Account's fields into the same query result.
  3. FROM Contact — the object being queried.
  4. ]; — closes the query.
  5. (blank line)
  6. for (Contact con : contacts) { — loops over the results.
  7. System.debug(con.LastName + ' works at ' + con.Account.Name); — no second query needed to fetch the parent's fields separately.
  8. } — closes the loop.

Traversing multiple levels

List<Contact> contacts = [
    SELECT Id, LastName, Account.Owner.Name
    FROM Contact
];
  1. List<Contact> contacts = [ — opens the query.
  2. SELECT Id, LastName, Account.Owner.Name — Account.Owner.Name reaches two levels up: from Contact to its parent Account, and from that Account to its owning User's Name.
  3. FROM Contact — the object being queried.
  4. ]; — closes the query. Salesforce supports traversing up to 5 relationship levels deep in a single SOQL query this way.

Why this beats a separate query

// DON'T DO THIS — a query inside a loop
for (Contact con : contacts) {
    Account acc = [SELECT Name FROM Account WHERE Id = :con.AccountId]; // a query per contact!
}
  1. // DON'T DO THIS — a query inside a loop — the label says it all.
  2. for (Contact con : contacts) { — loops over the contacts already in memory.
  3. Account acc = [SELECT Name FROM Account WHERE Id = :con.AccountId]; — a separate query runs for every single contact.
  4. } — closes the loop.

Warning: This is exactly the SOQL-in-a-loop governor limit problem revisited from Module 18 — line 3 runs a fresh query on every iteration, quickly hitting the 100-query-per-transaction limit with enough contacts and crashing with a System.LimitException. A single query with Account.Name in the SELECT clause (previous section) retrieves everything needed up front, entirely avoiding this.

Exercise

Write a query on Opportunity selecting Id, Name, and the parent Account's Name and Industry.

Show hint

SELECT Id, Name, Account.Name, Account.Industry FROM Opportunity

Salesforce: ○ Not connected Connect
APEX

Execution Results

Run your code to see the result.

Parent Relationship Queries Quiz

1. How many relationship levels can a single SOQL query traverse upward?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

A parent relationship query reaches through a lookup or master-detail relationship to pull parent fields in the very same query — this is the SOQL side of Module 18's relationship-traversal lesson.