我想创建一个类似于 SQL 中的谓词:
select f.type, f.variety, f.price
from (
select type, min(price) as minprice
from fruits group by type
) as x inner join fruits as f on f.type = x.type and f.price = x.minprice;
但是作为一个我不能用核心数据 block 中的谓词对其进行排序,我想知道如何使用 [NSPredicate predicateWithFormat:] 方法来编写它。
需要说明的是,我有一张“水果”表,其中包含列类型、品种和价格。我想为每种不同类型选择一行,其中价格是其类型中最低的。
最佳答案
在 Core Data 中,您将使用 NSExpression 来获取最小值,并且提取将以字典形式返回结果。所以,设置会有点不同。
您可以执行提取以获取每个最小值,执行如下操作:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:@"Fruit" inManagedObjectContext:myContext];
request.predicate = [NSPredicate predicateWithFormat:@"type = %@", @"banana"];
request.resultType = NSDictionaryResultType;
NSExpressionDescription *minExDescr = [[NSExpressionDescription alloc] init];
[minExDescr setName:@"myMinimum"];
[minExDescr setExpression:[NSExpression expressionForFunction:@"min:"
arguments:[NSArray arrayWithObject:
[NSExpression expressionForKeyPath:@"price"]]]];
[minExDescr setExpressionResultType:NSFloatAttributeType];
request.propertiesToFetch = [NSArray arrayWithObject:minExDescr];
NSError *err = nil;
NSArray *bananaResults = [self.moContext executeFetchRequest:request error:&err];
由于提取的结果是一个字典,您将按如下方式检索最小值:
NSDictionary *resultsDictionary = [bananaResults lastObject];
NSNumber *bananaMinimum = [resultsDictionary objectForKey:@"myMinimum"];
请注意,这只会为您提供最小值,而不是您请求的行(或托管对象)。然后,您可以通过使用复合谓词进行第二次提取来获取具有最小值的托管对象,以匹配类型和价格。 (我不知道在Core Data中是否可以直接一次获取托管对象。也许其他人可以评论。)
第二次获取的谓词如下:
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:
[NSArray arrayWithObjects:
[NSPredicate predicateWithFormat:@"type = %@", @"banana"],
[NSPredicate predicateWithFormat:@"price = %@", bananaMinimum],
nil]];
所有这些都假设您提前知道类型。如果您不这样做(即如果它们正在更改),您可以使用 setReturnsDistinctResults
通过初步获取来获取所有不同的类型。您将不得不再次将 setResultType
设置为 NSDictionaryResultType
。此外,setPropertiesToFetch
到包含您的类型属性的数组,以获取所有不同的类型。
只需按照 setDistinctResults
的文档和与上述相同的逻辑来设置提取。
此代码均未经过测试,因此可能存在拼写错误。
关于ios - NSPredicate Core Data iOS 中的子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18453611/