0

我想创建一个看起来像 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;

但是看到我无法使用带有核心数据块的谓词对它进行排序,我想知道如何使用 [NSPredicate predicateWithFormat:] 方法编写它。

需要明确的是,我有一个表格“水果”,列有类型、品种和价格。我想为每种不同类型选择一行,其中价格是其类型中的最小值。

4

1 回答 1

2

在 Core Data 中,您将使用 NSExpression 来获取最小值,并且 fetch 将以字典形式返回结果。所以,设置会有点不同。

您可以执行 fetch 以获取每个最小值,如下所示:

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];

由于 fetch 的结果是字典,因此您将检索最小值,如下所示:

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. 您将不得不再次这样setResultTypeNSDictionaryResultType。此外,setPropertiesToFetch对于包含您的 type 属性的数组,以获取所有不同的类型。
只需按照setDistinctResults上面的文档和相同的逻辑来设置提取。

此代码均未经过测试,因此可能存在拼写错误。

于 2013-08-27T03:55:46.943 回答