Search code examples
iosobjective-ccore-datanspredicatensfetchrequest

NSPredicate to get maximum value below a specified value


I have a Core Data based table of NSDates and numeric values.

I am trying to create a NSPredicate to get the numeric value for the maximum date which is below a given date, e.g. for DEC-31-2012, I would like to get DEC-30-2012 or DEC-29-2012 if this is the latest date before DEC-31-2012.

Unfortunately, my predicate does not work and results in a runtime crash:

NSFetchRequest *request = [NSFetchRequest 
   fetchRequestWithEntityName:NSStringFromClass([self class])];
NSPredicate *predicate = [NSPredicate 
   predicateWithFormat:@"SUBQUERY(SELF,$x,$x.date.@max <= %@)",endDate];

Error:

Unable to parse the format string "SUBQUERY(SELF,$x,$x.date.@max <= %@)"

How would I need to rewrite my predicate in order to get this correct?

Thank you!


Solution

  • The following strategy should work:

    • Use a predicate that fetches all objects with a date below the given date:

      NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date < %@", endDate];
      [request setPredicate:predicate];
      
    • Add a sort descriptor to sort the results by date descending, so that the last date comes first:

      NSSortDescriptor *sortDesc = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
      [request setSortDescriptors:@[sortDesc]];
      
    • Set the fetch limit to one:

      [request setFetchLimit:1];
      

    By setting the launch argument "-com.apple.CoreData.SQLDebug 1", one can see that the filtering is done on the SQLite level:

    SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZDATE, t0.ZNAME FROM ZENTITY t0 WHERE  t0.ZDATE < ? ORDER BY t0.ZDATE DESC LIMIT 1