我在Core Data中有一个表格,具有以下属性:
date, name, phone我想检索5个唯一的电话号码列表,其中包含按日期排序的名称。 所以在MySQL中它会是这样的:
SELECT name, phone FROM myTable GROUP BY phone ORDER BY date所以如果我有这个数据列表:
01/23/2015 someName1 12345678 01/21/2015 someName2 12345678 01/21/2015 someOtherName1 987654321我想检索一个唯一的电话号码列表,其中包含控制与任何重复号码关联的名称的日期字段。 在这种情况下,所需的结果是:
01/23/2015 someName1 12345678 01/21/2015 someOtherName1 987654321不过,使用NSFetchRequest这样做似乎有点复杂,因为setPropertiesToGroupBy需要包含setPropertiesToFetch定义的相同属性列表。
换句话说,我认为我能够做到这一点:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"someEntity" inManagedObjectContext:someContext]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:entity]; [request setResultType:NSDictionaryResultType]; [request setPropertiesToFetch:@[@"name", @"phone"]]; [request setPropertiesToGroupBy:@[@"phone"]]; [request setFetchLimit:5]; NSSortDescriptor *sortByCreatedDate = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO]; [request setSortDescriptors:@[sortByCreatedDate]];但是,除非我包含name字段,否则我将在propertiesToGroupBy上得到一个异常。
我怎样才能达到我想要的,而不必手动浏览列表?
I have a table in Core Data with the following properties:
date, name, phoneI want to retrieve a list of 5 unique phone numbers with names ordered by date. So in MySQL it would be something like:
SELECT name, phone FROM myTable GROUP BY phone ORDER BY dateSo if I have this list of data:
01/23/2015 someName1 12345678 01/21/2015 someName2 12345678 01/21/2015 someOtherName1 987654321I would like to retrieve a list of unique phone numbers with the date field controlling which name to be associated with any duplicated numbers. In this case, the desired result would be:
01/23/2015 someName1 12345678 01/21/2015 someOtherName1 987654321However doing this with a NSFetchRequest seems a bit complicated since the setPropertiesToGroupBy requires to contain the same list of properties as defined in setPropertiesToFetch.
In other words, this is how I would think I would be able to do it:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"someEntity" inManagedObjectContext:someContext]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:entity]; [request setResultType:NSDictionaryResultType]; [request setPropertiesToFetch:@[@"name", @"phone"]]; [request setPropertiesToGroupBy:@[@"phone"]]; [request setFetchLimit:5]; NSSortDescriptor *sortByCreatedDate = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO]; [request setSortDescriptors:@[sortByCreatedDate]];However I will get an exception on the propertiesToGroupBy unless I include the name field as well.
How can I achieve what I want without having to manually go through the list?
最满意答案
附带条件是我认为这会起作用; 我把它留给你来测试它的死亡:
您不能将任何其他属性添加到propertiesToFetch ,除了propertiesToFetch中的propertiesToGroupBy ,但您似乎可以在要提取的属性中包含objectID 。 为此,请为“评估对象”构建NSExpression和关联的NSExpressionDescription :
NSExpression *selfExp = [NSExpression expressionForEvaluatedObject]; NSExpressionDescription *selfED = [[NSExpressionDescription alloc] init]; selfED.name = @"objID"; selfED.expression = selfExp; selfED.expressionResultType = NSObjectIDAttributeType;现在定义另一个表达式/描述来获取最大值(日期):
NSExpression *maxDate = [NSExpression expressionForKeyPath:@"date"]; NSExpression *indexExp = [NSExpression expressionForFunction:@"max:" arguments:@[maxDate]]; NSExpressionDescription *maxED = [[NSExpressionDescription alloc] init]; maxED.name = @"maxDate"; maxED.expression = indexExp; maxED.expressionResultType = NSDateAttributeType;然后在要获取的属性列表中包含这两个表达式描述:
[request setPropertiesToFetch:@[@"phone", maxED, selfED]]; [request setPropertiesToGroupBy:@[@"phone"]];当您运行提取时,结果数组中的每个项目将具有包含相关对象的objectID的键“objID”。 你可以解压缩,通过这些行来访问名称,电话等等:
NSArray *results = [self.context executeFetchRequest:request error:&error]; for (NSDictionary *dict in results) { NSDate *maxDate = dict[@"maxDate"]; NSString *phone = dict[@"phone"]; NSManagedObjectID *objID = [dict valueForKey:@"objID"]; NSManagedObject *object = [self.context objectWithID:objID]; NSString *name = [object valueForKey:@"name"]; }我不确定的一个特定方面是如果两行具有完全相同的date这将如何表现。
With a proviso that I think this will work; I leave it to you to test it to death:
You cannot add any other attributes to propertiesToFetch, beyond those in the propertiesToGroupBy, but it seems you can include the objectID in the properties to fetch. To do so, build an NSExpression and associated NSExpressionDescription for the "evaluated object":
NSExpression *selfExp = [NSExpression expressionForEvaluatedObject]; NSExpressionDescription *selfED = [[NSExpressionDescription alloc] init]; selfED.name = @"objID"; selfED.expression = selfExp; selfED.expressionResultType = NSObjectIDAttributeType;Now define another expression/description to get the max(date):
NSExpression *maxDate = [NSExpression expressionForKeyPath:@"date"]; NSExpression *indexExp = [NSExpression expressionForFunction:@"max:" arguments:@[maxDate]]; NSExpressionDescription *maxED = [[NSExpressionDescription alloc] init]; maxED.name = @"maxDate"; maxED.expression = indexExp; maxED.expressionResultType = NSDateAttributeType;Then include these two expression descriptions in the list of properties to fetch:
[request setPropertiesToFetch:@[@"phone", maxED, selfED]]; [request setPropertiesToGroupBy:@[@"phone"]];When you run the fetch, each item in the resulting array will have a key "objID" containing the objectID for the relevant object. You can unpack that, to access the name, phone, etc, with something along these lines:
NSArray *results = [self.context executeFetchRequest:request error:&error]; for (NSDictionary *dict in results) { NSDate *maxDate = dict[@"maxDate"]; NSString *phone = dict[@"phone"]; NSManagedObjectID *objID = [dict valueForKey:@"objID"]; NSManagedObject *object = [self.context objectWithID:objID]; NSString *name = [object valueForKey:@"name"]; }One particular aspect I am unsure of is how this will behave if two rows have exactly the same date.
更多推荐
发布评论