I have a master-detail relation ship where I am updating the parent (lets call it Parent__c
) based on its child records aggregated values
(lets call the child, Child__c
).
The child has a relationship to another custom obj, lets call this one LookupObj__c
, in it a picklist, lets call it Category__c
.
I need a query that will determine the 2 most frequent LookupObj__c
picklist values based on the relationship with Child__c
. For this I came up with an
aggregate query that groups on Parent
, and on Category
then order on the count desc so that I get the highest 2 per parent first on the results
and where there is even results (lets say a match on category counts, then it is determined on category text comparison (so A_category would come before B_category)
So far I have something decent built where I get the results order the way I want BUT I am unsure how to get ONLY the first 2 most frequent LookupObj__c
values
for each parent and set that on the parent
Code:
for(AggregateResult ar: [SELECT count(id) cnt, LookupObj__r.Category__c cat, Parent__c Parent,
Parent__r.Primary_Category__c,Parent__r.Secondary_Category__c
FROM Child__c
WHERE Parent__c IN :ParentsToUpdateSet
GROUP BY Parent__c, LookupObj__r.Category__c ,
Parent__r.Primary_Category__c,Parent__r.Secondary_Category__c
order by Parent__c, count(id) desc, LookupObj__r.Category__c asc
]){
system.debug('aggregateResult: ' + ar);
Parent__c Parent = new Parent__c();
Parent.Id = (id)ar.get('Parent');
String cat = (String)ar.get('cat');
//HOW DO I GET THE 2 MOST FREQUENT CATEGORIES PER TRIP ASSIGNED???
parent.primary_category__c =
parent.seconday_Category__c =
}
Best Answer
There are several ways of doing this.
One would be to sort your GroupBy results using a for loop.
Another would be to put the results into map(s). Then take the top two results from your sorting in order to get them for the respective parents.
Since you're using a GroupBy, you could also presumably return something "like"
ar[0].cnt, ar[0].Parent__r.Primary_Category__c
andar[1].cnt, ar[1].Parent__r.Primary_Category__c
to get the top two for the parent with the "most" results and compare the twoParent_r's
to see if they're the same. If they're not, you have the two that you're looking for that are at the top.If they are the same, you'll need to test
ar[3]
,ar[4]
, etc until you find adifferent Parent__r
to assign as the second parent.From the above, you'll already know the results for the highest
Primary_Category__c
for thefirst Parent__r
and for the 2nd one as well. Now you need to sort the secondary category based on the what you learned determined to be the 1st and second parents.I believe this is where you may want to put the results into two maps.
Beginning with the 1st parent, do a for loop to add the results of a loop to the map if the parent and the
secondary_category__c
matchesparent__r
that was the1st parent
andsecondary_category__c isEmpty() == false
. The first result you find will be the one you're looking for. Rather than putting it into a map, you couldbreak
from thefor loop
if you wanted to. the choice would be yours to make.You'd repeat the same process above for the other
parent__r
.