So I have the following query that I am running through Batch Apex. I get the error:
System.LimitException: Too many query rows: 50001
I am receiving this because COUNT_DISTINCT() is subject to the same governor limits as other SOQL Queries. Basically I cannot think of a solution here, which is why I am posting this. The goal of the query is to see how many unique accounts an SDR is in contact with over a given time period. In this case, it is over a 120 day period. Would love some advice on how to achieve this.
String Contacts_Reached_TR_120_Query = 'SELECT Ownerid SDR_ID, COUNT_DISTINCT( whoid ) result FROM Task Where ActivityDate = LAST_N_DAYS:120 AND OwnerId in :ListOfIDs GROUP BY Ownerid';
DynamicBatchApexAR batch3_TR120 = new DynamicBatchApexAR('SDR_ID', 'result', 'Contacts_Reached_TR_120__c', Contacts_Reached_TR_120_Query, SDR_IDs);
Then here is the batch class
global class DynamicBatchApexAR implements Database.Batchable<AggregateResult> {
public String sObjectIdKey;
public String sObjectResultKey;
public String sObjectFieldToUpdate;
public String query;
public List<Id> ListOfIDs;
global DynamicBatchApexAR(String arIdKey, String arResultKey, String fieldToUpdate, String soqlQuery, List<Id> whereInClause )
{
sObjectIdKey = arIdKey;
sObjectResultKey = arResultKey;
sObjectFieldToUpdate = fieldToUpdate;
query = soqlQuery;
ListOfIDs = whereInClause;
}
global DynamicBatchApexAR(String arIdKey, String arResultKey, String fieldToUpdate, String soqlQuery )
{
sObjectIdKey = arIdKey;
sObjectResultKey = arResultKey;
sObjectFieldToUpdate = fieldToUpdate;
query = soqlQuery;
}
global Iterable<AggregateResult> start(Database.BatchableContext BC)
{
return ListOfIDs == null ? new BulkIterable(query) : new BulkIterable(query, ListOfIDs);
}
global void execute(Database.BatchableContext BC, List<sObject> scope)
{
DynamicSObjectUpdater sObjectUpdater = new DynamicSObjectUpdater();
for(sObject sObj: scope)
{
AggregateResult ar = (AggregateResult)sObj;
ID sObjectId = (ID)ar.get(sObjectIdKey);
Decimal arResult = (Decimal)ar.get(sObjectResultKey);
Map<String, Object> sObjectFieldsToUpdate = new Map<String, Object>{
sObjectFieldToUpdate => arResult
};
sObjectUpdater.getUpdateSObject(sObjectId, sObjectFieldsToUpdate);
}
sObjectUpdater.updateSObjects();
}
global void finish(Database.BatchableContext BC)
{
}
}
Here is the iterable
global with sharing class BulkIterable implements Iterable<AggregateResult> {
String query;
List<Id>
ListOfIDs;
global BulkIterable(String soql, List<Id> WhereInClause)
{
query = soql;
ListOfIDs = WhereInClause;
}
global BulkIterable(String soql)
{
query = soql;
}
global Iterator<AggregateResult> Iterator(){
return ListOfIDs == null ? new BulkIterator(query) : new BulkIterator(query, ListOfIDs);
}
}
Here is the iterator
global class BulkIterator implements Iterator<AggregateResult> {
AggregateResult[] results { get;set; }
Integer index { get;set; }
List<Id> ListOfIDs;
global BulkIterator(String query, List<Id> WhereInClause)
{
index = 0;
ListOfIDs = WhereInClause;
results = Database.query(query);
}
global BulkIterator(String query) {
index = 0;
results = Database.query(query);
}
global Boolean hasNext(){
return results != null && !results.isEmpty() && index < results.size();
}
global AggregateResult next() {
return results[index++];
}
}
Is the error because I am running too many batches?