SOQL Query: Accounts With Their Contacts

Parent-to-child SOQL that returns accounts together with their contacts, plus the relationship-name rules for custom objects.

Updated 2026-09-09

One query, two levels: a subquery in the SELECT list pulls each account's contacts along with the parent row - no second call, no manual joining.

Accounts sit at the top of most data models, so filters here usually cascade into contact, opportunity, and case reporting.

Parent to child (subquery)

The subquery uses the relationship name (Contacts), not the child object's API name. For custom objects the relationship name ends in __r.

Accounts and their contacts
SELECT Id, Name, Type,
  (SELECT Id, Name FROM Contacts)
FROM Account
LIMIT 50

Filter parents by a child condition

SOQL has no JOIN, but a semi-join with IN gets you the same result: query the child, feed the IDs into the parent filter.

Parents that have a recent child record
SELECT Id, Name, Type
FROM Account
WHERE Id IN (
  SELECT AccountId FROM Contact
  WHERE CreatedDate = LAST_N_DAYS:30
)

Relationship naming rules

  • Child to parent uses the lookup field with __r for custom fields: Account.Name, Custom_Lookup__r.Name.
  • Parent to child uses the child relationship name, which is plural for standard objects and _​_r-suffixed for custom ones.
  • You can dot-walk up to five levels toward a parent, but only one level down in a subquery.

Common mistakes to avoid

  • Use the API name Account, not the UI label - the two differ on several standard objects.
  • Wrap literal text values in single quotes; date literals such as LAST_N_DAYS:30 must stay unquoted.
  • Run the query in a sandbox first if it feeds a bulk update - a WHERE clause that is one character off can select the whole table.
  • Subquery rows count toward the total row limit, so a parent query with large child sets can blow past it unexpectedly.
  • The relationship name is set on the lookup field, and admins rename it - check the field definition rather than guessing.

Run it faster with TurboKit

Relationship queries are where autocomplete stops being a convenience and starts being the only practical way to write the query.

TurboKit's AI SOQL builder lets you describe the result you want in plain English, returns the query, and exports the rows to CSV or Excel in the same panel - without leaving the Salesforce tab you are already on.

Frequently asked questions

Does SOQL support JOIN?
No. SOQL replaces joins with relationship traversal (dot notation upward, subqueries downward) and semi-joins using IN with an inner query.
How many levels can I traverse?
Five levels from child to parent in a single query, and one level of parent-to-child subquery. Deeper structures need multiple queries.
Where do I find the relationship name?
Setup, then the lookup or master-detail field on the child object - the Child Relationship Name field. TurboKit's metadata viewer shows the same value inline on the record page.

More from the SOQL Library

Related reading