How to put sub query results into a List

Using SOQL, I have two objects, Book__c and Copy__c, Copy is a child of Book. I run a query with a subquery to get copies associated with a book where the copy has a certain status.

The results are what I expect in the Query Editor, but I have trouble putting it into a List in Apex code.

List<Book__c> BookList = [SELECT Id, (SELECT Id, Status__c FROM Copies__r WHERE Status__c = 'Available') FROM Book__c];

This results in a list containing only the Book ID, none of the copy related fields are written to the List. If I change the List to any other data type I get told I can’t convert from object type Book to String or whatever I am trying to use.

Can someone tell me the proper way to do this?


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

To access that list of Copies try using the following:


You should see some data if that query returned something.

You can also try to run your query in the query editor in the Developer Console you might understand it better then.

Method 2

This query of yours produces an outer list, with a child list on each one of those outer list items.

List<Book__c> BookList = [SELECT Id
                            , Name
                                (SELECT Id
                                    , Name
                                    , Status__c 
                                FROM Copies__r 
                                WHERE Status__c = 'Available') 
                            FROM Book__c];

Visually you could represent it like this:


In order to access the Copies children of each Book in this structure, you’re going to use the __r relationship to access each List<Copy__c>. (__r is a List of your subquery)

In a loop, they can be accessed like this:

for (Book__c book : BookList) {
    system.debug('Book: ' + book.Name);

    for (Copy__c copy : book.Copies__r) {

        // output both the book name and the copy name
        system.debug('Book: ' + book.Name + ' - Copy: ' + copy.Name);

You could also write your query from the perspective of the Copy__c object, which would return a different structure.

List<Copy__c> CopiesList = [SELECT Id
                                    , Name
                                    , Status__c
                                    , Book__r.Id // from the parent Book__c
                                    , Book__r.Name // from the parent Book__c
                                FROM Copy__c
                                WHERE Status__c = 'Available'];

In a similar loop, they can be accessed like this:

for (Copy__c copy : CopiesList) {

    // output both the book name and the copy name
    system.debug('Book: ' + copy.Book__r.Name + ' - Copy: ' + copy.Name);

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x