I have a SOQL query that pulls a list of accounts and associated contact records.

Is there a way to get the child contact records into a map without looping over the accounts and then looping over the contacts?

List<Account> accountsWithContacts = [SELECT ID, Name, (SELECT Id, Name FROM Contacts__r)
FROM Account];

Map<Id, Contact> contactMap = new Map<Id,Contact>();

If there are 7 contacts returned for a given Account I am trying to figure out the map syntax to extract just the child contacts into a map of of their own.

2 Answers 2


You can not get the map of contactId to Contact in an inner Query directly.

However, if you want to avoid looping over Account you can use a second query to get contacts by AccountId and store it in Map.


List<Account> accounts = [Select Id, Name From Account];
Map<Id, Contact> contacts = new Map<Id, Contact>([Select Id, Name From Contact Where AccountId in :accounts]);

As this query is Parent-child you cannot store directly from inner query as the correct map will be

Map<Id,Account> conMap = new Map<Id,Account>(accountsWithContacts);

so there is no way to fill your map directly from innerquery

instead you can make a map with accountId as a key and List as values as One account can have many contacts so the best way is to make a map like

Map<Id,List<Contact>> contactMap = new Map<Id,List<Contact>>();

and to fill this

List<Account> acList = new List<Account>([SELECT Id From Account Limit 100]);
List<Contact> conList = new List<Contact>([SELECT Id,AccountId From Contact WHERE AccountId in: acList]);

Map<Id,List<Contact>> contactMap = new Map<Id,List<Contact>>();

for(Contact con: conList){
        contactMap.put(con.AccountId,new List<Contact>());
System.debug('ContactMap :'+contactMap);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .