是否可以将 group_concat 与 coredata 一起使用?

Posted

技术标签:

【中文标题】是否可以将 group_concat 与 coredata 一起使用?【英文标题】:Is it possible to use group_concat with coredata? 【发布时间】:2013-12-17 14:59:35 【问题描述】:

我真的很努力将 coredata 与新的 ios 应用程序一起使用。

一个真正的挑战是,由于我的背景是 SQL,我一直在思考 SQLite 而不是 coredata。我已经解决了大多数障碍,但这让我很难过——我真的想创建一个返回 group_concat 的 SQLite 视图。

我是否需要通过在 Objective-c 中对结果进行编码来重新创建它,或者有没有办法使用 coredata 对象创建视图或发出直接 SQL?

编辑:添加了数据模型和期望的结果

表_A;列 -- 键、名称(注意 -- 键不是唯一的)

样本数据: K1, N1 K1、N2 K1, N3 K2, N1 K2、N2

期望的结果: K1, N1;N2;N3 K2, N1;N2

在 SQLite 中,这将是 SELECT 键,来自 Table_A GROUP BY 键的 GROUP_CONCAT(name)

【问题讨论】:

【参考方案1】:

如果您将获取请求设置为以字典形式返回结果,则您可以很好地控制分组。

http://mattconnolly.wordpress.com/2012/06/21/ios-core-data-group-by-and-count-results/ 和Core Data Fetching Properties with Group By Count 都包含很好的例子。第二个链接显示了如何通过关系的关键路径进行分组。

编辑:

在看到修改后的问题后,我稍微修改了一下。源码在Github上:https://github.com/halmueller/CoreDataGroupFetch

我找不到一个可以在单个查询中运行的解决方案。这是我能想到的最好的。它获取“键”字段的所有唯一值,然后遍历这些键并获取与该“键”匹配的所有对象。在第二次获取中,您可能想要获取 NSManagedObjects 而不是字典,具体取决于您要执行的操作。

NSFetchRequest* uniqueKeysFetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"KeyedName"];

uniqueKeysFetchRequest.propertiesToFetch = @[@"key"];
uniqueKeysFetchRequest.resultType = NSDictionaryResultType;
uniqueKeysFetchRequest.returnsDistinctResults = YES;

NSError* error = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:uniqueKeysFetchRequest
                                                            error:&error];
NSLog(@"uniqueKeysFetchRequest: %@", results);

NSLog(@"distinct values for \"key\": %@", [results valueForKeyPath:@"@distinctUnionOfObjects.key"]);

for (NSString *thisKey in [results valueForKey:@"key"]) 
    NSFetchRequest *oneKeyFetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"KeyedName"];
    NSString *predicateString = [NSString stringWithFormat:@"key LIKE '%@'", thisKey];
    oneKeyFetchRequest.predicate = [NSPredicate predicateWithFormat:predicateString];
    oneKeyFetchRequest.resultType = NSDictionaryResultType;
    oneKeyFetchRequest.propertiesToFetch = @[@"name"];
    NSLog(@"%@: %@", thisKey, [self.managedObjectContext executeFetchRequest:oneKeyFetchRequest error:&error]);

这会产生

results from uniqueKeysFetchRequest: (
        
        key = K1;
    ,
        
        key = K2;
    
)
distinct values for "key": (
    K1,
    K2
)
K1: (
        
        name = N2;
    ,
        
        name = N1;
    ,
        
        name = N3;
    
)
K2: (
        
        name = N2;
    ,
        
        name = N1;
    
)

我也试过

NSFetchRequest* fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"KeyedName"];

fetchRequest.propertiesToFetch = @[@"key", @"name"];
fetchRequest.propertiesToGroupBy = @[@"key", @"name"];
fetchRequest.resultType = NSDictionaryResultType;
fetchRequest.returnsDistinctResults = YES;

NSError* error = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest
                                                            error:&error];
NSLog(@"withKeypathStrings: %@", results);

NSLog(@"distinct values for \"key\": %@", [results valueForKeyPath:@"@distinctUnionOfObjects.key"]);

这可能更接近你想要的:

withKeypathStrings: (
        
        key = K1;
        name = N1;
        ,
        
        key = K1;
        name = N2;
    ,
        
        key = K1;
        name = N3;
    ,
        
        key = K2;
        name = N1;
    ,
        
        key = K2;
        name = N2;
    
)
distinct values for "key": (
    K2,
    K1
)

【讨论】:

很好,这适用于计数。即“Key”,“3”,但不是我想要的...... group_concat 给我的结果类似于“Key”,“data1,data2,data3”【参考方案2】:

您可以使用 NSExpression(forFunction: "count:") 或其他带有数字 https://developer.apple.com/documentation/foundation/nsexpression/1413747-init 的函数在 Core Data 中实现 group_concat 但是没有办法让字符串 concat 像 "name1, name2, name3..." 因为 Core Data 不支持自定义 NSExpression 函数

【讨论】:

以上是关于是否可以将 group_concat 与 coredata 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL GROUP_CONCAT 与 Nulls

在 SQLite 中,多个列的排序方式是不是与 group_concat 相同?

Hibernate:如何使用 CONCAT 和 GROUP_CONCAT

MySQL group_concat 与 where 子句

可以将 Core Data 与不同的预填充 sqlite db 一起使用吗?

MySQL group_concat 与连接