Distinct Count via Core Data, NSExpression Into NSFetchedResultsController

后端 未结 2 2019
遇见更好的自我
遇见更好的自我 2020-12-30 13:16

Currently using Core Data. I have one table in which I am trying to retrieve information along these lines:

SELECT item, COUNT(*) FROM myTab         


        
相关标签:
2条回答
  • 2020-12-30 13:53

    It made more sense to just write my own query. I followed this excellent tutorial:

    http://dblog.com.au/iphone-development-tutorials/iphone-sdk-tutorial-reading-data-from-a-sqlite-database/

    0 讨论(0)
  • 2020-12-30 14:15

    This is possible with NSExpression as you originally proposed, in my contrived example I have an entity called "Person" with a property called "emailAddress" that I wish to get the count for.

    NSPropertyDescription *propDesc = [[[[model entitiesByName] objectForKey:@"Person"] propertiesByName] objectForKey:@"emailAddress"];
    NSExpression *emailExpr = [NSExpression expressionForKeyPath:@"emailAddress"];
    NSExpression *countExpr = [NSExpression expressionForFunction:@"count:" arguments:[NSArray arrayWithObject:emailExpr]];
    NSExpressionDescription *exprDesc = [[NSExpressionDescription alloc] init];
    [exprDesc setExpression:countExpr];
    [exprDesc setExpressionResultType:NSInteger64AttributeType];
    [exprDesc setName:@"count"];
    
    NSFetchRequest *fr = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
    [fr setPropertiesToGroupBy:[NSArray arrayWithObject:propDesc]];
    [fr setPropertiesToFetch:[NSArray arrayWithObjects:propDesc, exprDesc, nil]];
    [fr setResultType:NSDictionaryResultType];
    NSArray *results = [moc executeFetchRequest:fr error:&error];
    

    I wrote a snippet of code to pre-populate the database with 1000 records:

    NSArray *emailAddresses = [NSArray arrayWithObjects:@"test@test.com", @"1@1.com", @"1@2.com", @"roam@test.com", @"foo@foo.com", nil];
        for (int i = 0; i < 1000; i++) {
            NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:moc];
            [person setValue:[NSNumber numberWithInt:i] forKey:@"aNumber"];
            [person setValue:[[NSUUID UUID] UUIDString] forKey:@"aUUID"];
            [person setValue:[emailAddresses objectAtIndex:(i % [emailAddresses count])] forKey:@"emailAddress"];
        }
    

    The above code will insert each email address 200 times, here are the results:

    2012-05-31 15:17:42.160 Scratch[16084:10d03] CoreData: sql: SELECT t0.ZEMAILADDRESS, COUNT( t0.ZEMAILADDRESS) FROM ZPERSON t0 GROUP BY  t0.ZEMAILADDRESS 
    2012-05-31 15:17:42.162 Scratch[16084:10d03] CoreData: annotation: sql connection fetch time: 0.0024s
    2012-05-31 15:17:42.163 Scratch[16084:10d03] CoreData: annotation: total fetch execution time: 0.0029s for 5 rows.
    (gdb) po results
    (NSArray *) $2 = 0x0f811280 <_PFArray 0xf811280>(
    {
        count = 200;
        emailAddress = "1@1.com";
    },
    {
        count = 200;
        emailAddress = "1@2.com";
    },
    {
        count = 200;
        emailAddress = "foo@foo.com";
    },
    {
        count = 200;
        emailAddress = "roam@test.com";
    },
    {
        count = 200;
        emailAddress = "test@test.com";
    }
    )
    
    0 讨论(0)
提交回复
热议问题