[SalesForce] Issue processing data from aggregate result query

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 and ar[1].cnt, ar[1].Parent__r.Primary_Category__c to get the top two for the parent with the "most" results and compare the two Parent_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 a different Parent__r to assign as the second parent.

From the above, you'll already know the results for the highest Primary_Category__c for the first 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 matches parent__r that was the 1st parent and secondary_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 could break from the for loop if you wanted to. the choice would be yours to make.

You'd repeat the same process above for the other parent__r.

Related Topic