Skip to content Skip to sidebar Skip to footer

Is It Possible To Use Group_concat With Coredata?

I am really trying hard to use coredata with a new IOS application. A real challenge is that since my background is SQL, I keep thinking in terms of SQLite rather than coredata.

Solution 1:

If you set your fetch request to return results as dictionaries, you have a lot of control over grouping.

http://mattconnolly.wordpress.com/2012/06/21/ios-core-data-group-by-and-count-results/ and Core Data Fetching Properties with Group By Count both contain good examples. The second link shows how to walk down a relationship's keypath for grouping.

EDIT:

After seeing revised question, I tinkered with this a bit. Source code is on Github: https://github.com/halmueller/CoreDataGroupFetch

I couldn't get a solution that would work in one single query. This is the best I could come up with. It fetches all of the unique values for the "key" field, then iterates over those keys and fetches all objects matching that "key". In the second fetch, you might want to fetch NSManagedObjects instead of dictionaries, depending on what you're going to do.

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

This yields

results from uniqueKeysFetchRequest:(
        {
        key=K1;
    },
        {
        key=K2;
    }
)distinctvaluesfor"key":(K1,K2)K1:(
        {
        name=N2;
    },
        {
        name=N1;
    },
        {
        name=N3;
    }
)K2:(
        {
        name=N2;
    },
        {
        name=N1;
    }
)

I also tried

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

which might be closer to what you want:

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
)

Solution 2:

You can implement group_concat with Core Data using NSExpression(forFunction: "count:") or other functions with numbers https://developer.apple.com/documentation/foundation/nsexpression/1413747-init But there is no way to make string concat like "name1, name2, name3..." because Core Data doesn't support custom NSExpression functions

Post a Comment for "Is It Possible To Use Group_concat With Coredata?"