2013-08-26 41 views
0

我想打一個謂語,看起來像等值SQL:子查詢中NSPredicate核心數據的iOS

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:]方法編寫此代碼。

要清楚,我有一個表'水果'與列類型,品種和價格。我想爲每種不同的類型選擇一行,其中價格在其類型中是最小的。

回答

2

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

請注意,這隻會給你最小值,而不是你所要求的行(或管理對象)。然後,您可以通過使用複合謂詞進行第二次獲取來獲取具有最小值的受管理對象,以匹配類型和價格。 (我不知道是不是在覈心數據就可以得到管理對象直接在一個取也許別人可以發表評論。)

第二提取將如下所示的謂詞:

NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates: 
          [NSArray arrayWithObjects: 
          [NSPredicate predicateWithFormat:@"type = %@", @"banana"], 
          [NSPredicate predicateWithFormat:@"price = %@", bananaMinimum], 
          nil]]; 

所有這一切都假設你提前知道類型。如果你不知道(即如果他們正在改變),你可以通過使用setReturnsDistinctResults進行初步獲取來獲得所有不同的類型。您將再次需要setResultTypeNSDictionaryResultType。另外,setPropertiesToFetch包含您的類型屬性的數組,以獲取所有不同的類型。
只需按照setDistinctResults的文檔以及與上述相同的邏輯設置提取。

這段代碼沒有經過測試,所以可能會有拼寫錯誤。