Newer Version Available

This content describes an older version of this product. View Latest

Understanding Query Results

Query results are returned as nested objects. The primary or “driving” object of the main SELECT statement in a SOQL query contains query results of subqueries.

For example, you can construct a query using either parent-to-child or child-to-parent syntax:

  • Child-to-parent:
    1SELECT Id, FirstName, LastName, AccountId, Account.Name
    2FROM Contact 
    3WHERE Account.Name LIKE 'Acme%'

    This query returns one query result (assuming there were not too many returned records), with a row for every contact that met the WHERE clause criteria.

    1
    2  "records": [
    3    {
    4      "attributes": {
    5        "type": "Contact",
    6        "url": "/services/data/v65.0/sobjects/Contact/003R000000A1BCDFXX"
    7      },
    8      "Id": "003R000000A1BCDFXX",
    9      "FirstName": "Jane",
    10      "LastName": "Doe",
    11      "AccountId": "001R000000Z1Y0xYAA",
    12      "Account": {
    13        "attributes": {
    14          "type": "Account",
    15          "url": "/services/data/v65.0/sobjects/Account/001R000000Z1Y0xYAA"
    16        },
    17        "Name": "Acme Corp (West)"
    18      }
    19    },
    20    {
    21      "attributes": {
    22        "type": "Contact",
    23        "url": "/services/data/v65.0/sobjects/Contact/003R000000A2CDEBZZ"
    24      },
    25      "Id": "003R000000A2CDEBZZ",
    26      "FirstName": "John",
    27      "LastName": "Smith",
    28      "AccountId": "001R000000Z1Y0zYBB",
    29      "Account": {
    30        "attributes": {
    31          "type": "Account",
    32          "url": "/services/data/v65.0/sobjects/Account/001R000000Z1Y0zYBB"
    33        },
    34        "Name": "Acme Global Solutions"
    35      }
    36    }
    37  ]
    38      
  • Parent-to-child:
    1SELECT Id, Name,
    2  (
    3    SELECT Id, FirstName, LastName
    4    FROM Contacts
    5  )
    6FROM Account
    7  WHERE Name like 'Acme%'

    This query returns a set of accounts, and within each account, a query result set of Contact fields containing the contact information from the subquery.

    1
    2         "records": [
    3    {
    4      "attributes": {
    5        "type": "Account",
    6        "url": "/services/data/v65.0/sobjects/Account/001R000000Z1Y0xYAA"
    7      },
    8      "Id": "001R000000Z1Y0xYAA",
    9      "Name": "Acme Corp (West)",
    10      "Contacts": {
    11        "totalSize": 2,
    12        "done": true,
    13        "records": [
    14          {
    15            "attributes": { "type": "Contact", "url": "/services/data/v65.0/sobjects/Contact/003R000000A1BCDFXX" },
    16            "Id": "003R000000A1BCDFXX",
    17            "FirstName": "Jane",
    18            "LastName": "Doe"
    19          },
    20          {
    21            "attributes": { "type": "Contact", "url": "/services/data/v65.0/sobjects/Contact/003R000000A3EFGHYY" },
    22            "Id": "003R000000A3EFGHYY",
    23            "FirstName": "David",
    24            "LastName": "Jones"
    25          }
    26        ]
    27      }
    28    },
    29    {
    30      "attributes": {
    31        "type": "Account",
    32        "url": "/services/data/v65.0/sobjects/Account/001R000000Z1Y0zYBB"
    33      },
    34      "Id": "001R000000Z1Y0zYBB",
    35      "Name": "Acme Global Solutions",
    36      "Contacts": {
    37        "totalSize": 1,
    38        "done": true,
    39        "records": [
    40          {
    41            "attributes": { "type": "Contact", "url": "/services/data/v65.0/sobjects/Contact/003R000000A2CDEBZZ" },
    42            "Id": "003R000000A2CDEBZZ",
    43            "FirstName": "John",
    44            "LastName": "Smith"
    45          }
    46        ]
    47      }
    48    }
    49  ]
    50      

The following sample illustrates how to process subquery results:

1private void querySample() {
2  QueryResult qr = null;
3  try {
4    qr = connection.query("SELECT a.Id, a.Name, " +
5      "(SELECT c.Id, c.FirstName, " +
6      "c.LastName FROM a.Contacts c) FROM Account a");
7    boolean done = false;
8    if (qr.getSize() > 0) {
9      while (!done) {
10        for (int i = 0; i < qr.getRecords().length; i++) {
11        Account acct = (Account) qr.getRecords()[i];
12        String name = acct.getName();
13        System.out.println("Account " + (i + 1) + ": " + name);
14        printContacts(acct.getContacts());
15        }
16        if (qr.isDone()) {
17          done = true;
18        } else {
19          qr = connection.queryMore(qr.getQueryLocator());
20        }
21      }
22    } else {
23      System.out.println("No records found.");
24    }
25    System.out.println("\nQuery succesfully executed.");
26  } catch (ConnectionException ce) {
27    System.out.println("\nFailed to execute query successfully, error message " +
28    "was: \n" + ce.getMessage());
29  }
30}
31
32private void printContacts(QueryResult qr) throws ConnectionException {
33  boolean done = false;
34  if (qr.getSize() > 0) {
35    while (!done) {
36    for (int i = 0; i < qr.getRecords().length; i++) {
37      Contact contact = (Contact) qr.getRecords()[i];
38      String fName = contact.getFirstName();
39      String lName = contact.getLastName();
40      System.out.println("Child contact " + (i + 1) + ": " + lName 
41      + ", " + fName);
42    }
43    if (qr.isDone()) {
44      done = true;
45    } else {
46      qr = connection.queryMore(qr.getQueryLocator());
47    }
48    }
49  } else {
50    System.out.println("No child contacts found.");
51  }
52}