0

I have got two objects Account and AccountLocation__c with a master-detail relationship where AccountLocation__c.Account__c references Account.ID. Manual check does confirm the relationship.

The parent to child query:

SELECT Account.ID, (SELECT Account__c FROM Account.AccountLocations__r) FROM Account

returns the rows while the child to parent query:

SELECT Account__c, AccountLocations__r.Account.ID FROM AccountLocation__c

results in the error

Didn't understand relationship 'AccountLocations__r' in field path. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names.

Another question is that the second query returns of the form

ID, AccountLocations__r[{"Account__c":id1}, {"Account__c":id2}]

Considering the cardinalities, how can I extract only the IDs here?

1

There's really no need to use table names in your query (e.g. select account.id from account), but if you are insisting on using them, then your second query probably should have been:

SELECT Account__c, AccountLocations__c.Account__r.ID FROM AccountLocation__c

Use __r only to refer to a relationship. The table name doesn't change to __r. This is one reason I tend to avoid table names/aliases in straight queries, because it complicates otherwise easy code.

As a side note, Account__c and Account__r.Id refer to the same value. You really wouldn't normally refer to both of them that way.

The second query wouldn't return that form, although the first would (I presume this what you meant). Extracting the values can be done several ways. One possible way to get just Id values could look like:

Set<Id> ids = new Map<Id, AccountLocation__c>(results[0].AccountLocation__r).keySet();

However, depending on your use case, you might not even need to do that. You can bind an SObject list to a query variable, for example, and the query returns all values that match the IDs in the list.

You could also do this a bit more manually and just loop through the values and add them to a list or set.

4
  • AccountLocation being the Child object, will it have a field Account__r when Account is the parent? – Santanu Halder Apr 30 '15 at 19:51
  • @SantanuHalder It'll be whatever the field's name is that defines the relationship. I presumed it was probably called Account__c, being the most logical choice, so the relationship name going up would be Account__r. – sfdcfox Apr 30 '15 at 19:54
  • I dont mean to be too nasty, but your last statement, "going up would be Account_r", I think the parent(Account) will have a field with name AccountLocation__r, the child(AccountLocation) will have Account__c instead. – Santanu Halder Apr 30 '15 at 20:09
  • The parent has a relationship (not a "field") that's probably called AccountLocation__r (but you can rename it!), and the child has the field Account__c with the relationship Account__r. For example, you would query Account__c to get the account's ID (the value in the field), but Account__r.Name to get the account's name by going through the relationship. – sfdcfox Apr 30 '15 at 20:15
0

Consider 2 object, Parent & Child. In Parent object the relationship stands as a List of Children(One to many). Childs__r is the API of the relationship field from Parent's point of view.

If you query from Parent Object and want to access children,

Select Parent.Id, (select Id from Childs__r) from Parent

Again, in Child object the same relationship stands as one Parent reference field. This is because one child can have only one parent, so the API for this field from Child's point of view is Child.Parent__c.

If you query from Child Object and want to access Parent

Select Id, Parent__c from Child

Your 2nd query is incorrect as in Child object there is no Childs__r field. Its all about from which object you are calling the query.

I was not able to get your last question, care to explain?

2
  • Ok, I understand that the relationshipname field is not accessible from child to parent query. My concern is that there are similar objects that have the values of the field referencing the parent as empty. Must mean that cascadeDelete property must be false. I wanted to query only the non-empty referencing fields and that is the reason for using two Id fields - One with the child and other with the parent. How would I go about this? – dmachop Apr 30 '15 at 20:14
  • In child object, relationship is available through ParentObject__c field name. Next, if you have empty parent's field in any child record, that means either the relationship is look up or cascade is false like you said. Now to query only the child records with non-empty parent field, use this- Select id, parent__c from Child where parent__c <> null – Santanu Halder Apr 30 '15 at 21:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.