核心数据的GROUP BY等价物

时间:2011-02-01 17:13:00

标签: iphone sql objective-c core-data

我知道我可以使用@distinctUnionOfObjects在SQL中找到类似下面的内容:

SELECT a_value
FROM my_table
GROUP BY a_value;

我正在寻找的是数组中返回的所有数据,而不仅仅是按表达式匹配组的值数组。基本上,我正在寻找核心数据的以下SQL查询的等价物:

SELECT *
FROM my_table
GROUP BY a_value;

4 个答案:

答案 0 :(得分:17)

这是模拟

SELECT 'Status', COUNT(*) FROM 'Records' GROUP BY 'Status'

NSFetchRequest* fetch = [NSFetchRequest fetchRequestWithEntityName:@"Record"];
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Record"
                                          inManagedObjectContext:myManagedObjectContext];
NSAttributeDescription* statusDesc = [entity.attributesByName objectForKey:@"status"];
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"url"]; // Does not really matter
NSExpression *countExpression = [NSExpression expressionForFunction: @"count:"
                                                          arguments: [NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName: @"count"];
[expressionDescription setExpression: countExpression];
[expressionDescription setExpressionResultType: NSInteger32AttributeType];
[fetch setPropertiesToFetch:[NSArray arrayWithObjects:statusDesc, expressionDescription, nil]];
[fetch setPropertiesToGroupBy:[NSArray arrayWithObject:statusDesc]];
[fetch setResultType:NSDictionaryResultType];
NSError* error = nil;
NSArray *results = [myManagedObjectContext executeFetchRequest:fetch
                                                         error:&error];

Found here

答案 1 :(得分:3)

您可以尝试使用NSFetchedResultsController对象通过初始化程序中的sectionNameKeyPath构造提供分组。请注意,FRC主要用于与表视图耦合,但实际上并不是必需的。这样您就可以通过sectionNameKeyPath对结果进行分组,这也可能是模型中的瞬态属性。

作为评论,我不建议根据数据库来考虑核心数据,但事实并非如此。构建核心数据是为了使您更容易持久化和管理对象关系。仅仅因为在iOS上它运行在SQLite之上并不能使它成为数据库的替代品。

参考:NSFRC Reference

答案 2 :(得分:0)

我发现这种方法(大致类似于接受的答案)更清洁,更容易理解。这是SQL等效于:

SELECT COUNT(*), a_value FROM my_table GROUP BY a_value;

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[MyTable className]];

// create expression for grouped column
NSExpressionDescription *aValueDescription = [[NSExpressionDescription alloc] init];
aValueDescription.name = @"aValue"; // name of key in result dictionary
aValueDescription.expression = [NSExpression expressionWithFormat:@"aValue"];
aValueDescription.expressionResultType = NSObjectIDAttributeType;

// create expression for count
NSExpressionDescription *countDescription = [[NSExpressionDescription alloc] init];
countDescription.name = @"count"; // name of dictionary key in result dictionary
countDescription.expression = [NSExpression expressionWithFormat:@"aValue.@count"];
countDescription.expressionResultType  = NSInteger32AttributeType;

// fill out fetch request
fetchRequest.propertiesToGroupBy = @[@"aValue"];
fetchRequest.propertiesToFetch = @[aValueDescription, countDescription];
//fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"count" ascending:NO]]; // not sure why this crashes
fetchRequest.resultType = NSDictionaryResultType; // required for "group by" requests

NSError *error = nil;
NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

返回的results是一个NSDictionary数组。请注意,描述name属性可以是您想要的任何内容 - 它们只是返回词典中键的名称。可以向获取请求添加谓词以从表中过滤行;此代码返回所有行。

奖励指向任何可以告诉我如何使排序描述符工作的人......

答案 3 :(得分:-1)

您可以使用Predicate Programming

编辑:抱歉,您不能将分组使用谓词至少不是直截了当。我刚看了参考文献。

  

限制:您不一定能将“任意”SQL查询转换为谓词或获取请求。例如,无法转换SQL语句,例如

SELECT t1.name,V1,V2

FROM table1 t1 JOIN (SELECT t2.name AS V1, count(*) AS V2

    FROM table2 t2 GROUP BY t2.name as V) on t1.name = V.V1