I have a custom sObject which has among others the following fields: email__c (email), some_date__c (date), external_id__c (integer) and criteria__c (string). There are multiple records for this sObject that have the same value for email__c.
If an email address returned in the results has multiple records we want to select the record with the most recent date. If there is a tie on the date then select the record with the greatest external id. However we only want to return the selected record if it matches the criteria.
Below is how I have been able to do this with Apex code but I am wondering if there is a way I can accomplish the same with a single SOQL query or with simpler code. Any suggestions?
public List<Project__c> getRecords(String criteria) {
List<String> emails = new List<String>();
Map<String, Project__c> emailProjectMap = new Map<String, Project__c>();
List<Project__c> retVal = new List<Project__c>();
for( Project__c project : [ Select email__c From Project__c
Where criteria__c = :criteria ] ) {
emails.add(project.email__c);
}
for( Project__c project : [ Select email__c, some_date__c, external_id__c, criteria__c
From Project__c Where email__c in :emails
Order by some_date__c, external_id__c ] ) {
emailProjectMap.put(project.email__c, project);
}
for( Project__c project : emailProjectMap.values() ) {
if( project.criteria__c == criteria ) {
retVal.add(project);
}
}
return retVal;
}
Here is some sample data demonstrating the different cases that occur:
email__c some_date__c external_id__c criteria__c
[email protected] 2012-11-16 1 good
[email protected] 2012-08-20 2 good
[email protected] 2012-11-11 3 good
[email protected] 2012-11-13 4 good
[email protected] 2012-09-14 5 good
[email protected] 2012-10-02 6 good
[email protected] 2012-10-02 7 good
[email protected] 2012-07-30 8 good
[email protected] 2012-11-14 9 bad
If the criteria that we are searching for is "good" there should be 4 records returned. Below is the list of records that should be returned by the function.
email__c some_date__c external_id__c criteria__c
[email protected] 2012-11-16 1 good
[email protected] 2012-11-11 3 good
[email protected] 2012-11-13 4 good
[email protected] 2012-10-02 7 good
Note:
- The record with the max(some_date__c) for an email address may not have the max(external_id__c)
- This is why the record with external_id__c = 4 is returned for the email [email protected] instead of external_id__c = 5
- A record for an email address may match the criteria but the record with the max(some_date__c) and if there is a tie the max(external_id__c) may not match the criteria
- This is why there is no record returned for the email [email protected]