You need to sign in to do that
Don't have an account?
SeanGorman
Trying to use aggregate function with more than one 'group by'
I'm writing a class that fires on insert/update of a trigger on the OpportunityLineItem. This looks at a picklist field (Play__c) on Product2.
When Opportunity products are added (which may be in batches) I need to count the number of each possible variation in the picklist for each account.
Opp 1 has 5 products added. 2 are Red, 2 are Black and one is White. There are a number of fields on the Opp: isRed, isBlack and IsWhite into which those number must go.
My first take is that an aggregate function would do. My Primary key is Oppid and Play__c in order to count Play__c:
AggregateResult[] OppLineItemsPlays = [select OpportunityId, COUNT(id), PricebookEntry.Product2.Play__c
from OpportunityLineItem
where OpportunityId in: oppid
group by OpportunityId, PricebookEntry.Product2.Play__c];
System.debug('\n ------------------->OppLineItemsPlays = ' + OppLineItemsPlays);
for(AggregateResult OLIPlays: OppLineItemsPlays) {
opportunityCount.put((ID) OLIPlays.get('OpportunityId'), (Integer)OLIPlays.get('expr0'));
System.debug('\n ------------------->Opportunity id = ' + OLIPlays.get('OpportunityId'));
System.debug('\n ------------------->Play__c = ' + OLIPlays.get('Play__c'));
System.debug('\n ------------------->count = ' + OLIPlays.get('expr0'));
System.debug('\n ------------------->OLIPlays = ' + OLIPlays);
// }
This gives me a count of all of the times that each Play has been selected in Products in OLIs and gives me the name of the play.
Here is my issue and its a bit silly: how would you proceed from here?
My thoughts are to create a new map for every variation of Play and then add the Oppid, Count(Play__c). This means that I have to know every possible play (which I do) and can control the creation of new ones (which I can)
Alternatively a map of ids to a map of strings to integers: [map<id, map<string, integer>> opptyPlayCount = new map<id, map<string, integer>>();]
when I get to saving this I have the Oppids.
for(Id opptyId : summedOpptyIds) {
opps.add(new Opportunity(
Id = opptyId,
Booking_Amount__c = totalBookingAmts.get(opptyId)
isRed = .................
));
}
When Opportunity products are added (which may be in batches) I need to count the number of each possible variation in the picklist for each account.
Opp 1 has 5 products added. 2 are Red, 2 are Black and one is White. There are a number of fields on the Opp: isRed, isBlack and IsWhite into which those number must go.
My first take is that an aggregate function would do. My Primary key is Oppid and Play__c in order to count Play__c:
AggregateResult[] OppLineItemsPlays = [select OpportunityId, COUNT(id), PricebookEntry.Product2.Play__c
from OpportunityLineItem
where OpportunityId in: oppid
group by OpportunityId, PricebookEntry.Product2.Play__c];
System.debug('\n ------------------->OppLineItemsPlays = ' + OppLineItemsPlays);
for(AggregateResult OLIPlays: OppLineItemsPlays) {
opportunityCount.put((ID) OLIPlays.get('OpportunityId'), (Integer)OLIPlays.get('expr0'));
System.debug('\n ------------------->Opportunity id = ' + OLIPlays.get('OpportunityId'));
System.debug('\n ------------------->Play__c = ' + OLIPlays.get('Play__c'));
System.debug('\n ------------------->count = ' + OLIPlays.get('expr0'));
System.debug('\n ------------------->OLIPlays = ' + OLIPlays);
// }
This gives me a count of all of the times that each Play has been selected in Products in OLIs and gives me the name of the play.
Here is my issue and its a bit silly: how would you proceed from here?
My thoughts are to create a new map for every variation of Play and then add the Oppid, Count(Play__c). This means that I have to know every possible play (which I do) and can control the creation of new ones (which I can)
Alternatively a map of ids to a map of strings to integers: [map<id, map<string, integer>> opptyPlayCount = new map<id, map<string, integer>>();]
when I get to saving this I have the Oppids.
for(Id opptyId : summedOpptyIds) {
opps.add(new Opportunity(
Id = opptyId,
Booking_Amount__c = totalBookingAmts.get(opptyId)
isRed = .................
));
}
Before your Aggregate query you need to fill a map
Map<Id, Opportunity> mapOpps = new Map<Id, Opportunity>();
Now fill this map like
mapOpps.put(OpportunityLineItem.OpportunityId, new Opportunity(Id= OpportunityLineItem.OpportunityId, isRed = null, isBlack = null, IsWhite = null));
Now your query like
AggregateResult[] OppLineItemsPlays = [Select OpportunityId oppId, PricebookEntry.Product2.Play__c playName, Count(Id) cnt From OpportunityLineItem Where
OpportunityId IN : mapOpps.keySet() GROUP BY ROLLUP (OpportunityId, PricebookEntry.Product2.Play__c)]
for(AggregateResult aggResult : OppLineItemsPlays) {
//Opportunity Id
Id oppId = Id.valueOf(String.valueOf(aggResult.get('oppId')));
String playName = String.valueOf(aggResult.get('playName'));
//Now check for Play Name
if(playName == 'Red') {
mapOpps.get(oppId).isRed = Integer.valueOf(aggResult.get('cnt'));
} else if(playName == 'Black') {
mapOpps.get(oppId).isBlack = Integer.valueOf(aggResult.get('cnt'));
}......
}
//Check for size
if(mapOpps.size() > 0)
update mapOpps.values();