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}