2011-02-03 5 views
0

Я хотел бы иметь эквивалент ядро ​​данных функции SQL:подсчет различных

SELECT species, sex, COUNT(*) FROM Bird GROUP BY species, sex; 

запрос, который, как правило, вернуть этот

+---------+------+----------+ 
| species | sex | COUNT(*) | 
+---------+------+----------+ 
| Bus  | m |  2 | 
| Car  | f |  1 | 
+---------+------+----------+ 

со следующими записями:

INSERT INTO Bird VALUES ('BlueBird','Car','f'); 
INSERT INTO Bird VALUES ('RedBird','Bus','m'); 
INSERT INTO Bird VALUES ('RedBird','Bus','m'); 

Я выполнил отдельный запрос, но у меня возникли проблемы с подсчетом (*). Вот что у меня есть:

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Bird" inManagedObjectContext:managedObjectContext]; 
[request setEntity:entity]; 
[request setReturnsDistinctResults:YES]; 
[request setResultType:NSDictionaryResultType]; 
NSDictionary *entityProperties = [entity propertiesByName]; 

NSMutableArray *properties = [NSMutableArray arrayWithObject:[entityProperties objectForKey:@"species"]]; 
[properties addObject:[entityProperties objectForKey:@"sex"]]; 
[request setPropertiesToFetch: properties]; 

Что я должен добавить?

Большое спасибо

ответ

1

модель данных, подразумеваемые данным выборки предполагает, что вы должны были бы получать каждый объект, фильтр и повторно принести:

NSManagedObjectContext *moc; 
NSEntityDescription *birdEntity = [NSEntityDescription entityForName:"Bird" inManagedObjectContext:moc]; 

NSFetchRequest *fetchAllBirds = [[NSFetchRequest new] autorelease]; 
[fetchAllBirds setEntity:birdEntity]; 
NSArray *allBirds = [moc executeFetchRequest:fetchAllBirds error:NULL]; 

NSArray *species = [allBirds valueForKeyPath:@"@distinctUnionOfObjects.species"]; 

NSMutableDictionary *speciesCounts = [NSMutableDictionary dictionaryWithCapacity: [species count]]; 
for (NSString *speci in species) 
{ 
    NSFetchRequest *fetchSpeci = [[NSFetchRequest new] autorelease]; 
    [fetchSpeci setEntity: birdEntity]; 
    [fetchSpeci setPredicate:[NSPredicate predicateWithFormat:@"speci == %@", speci]]; 

    int speciCount = [moc countForFetchRequest:fetchSpeci]; 
    [speciesCounts setObject:[NSNumber numberWithInt:speciCount] forKey:speci]; 
} 

Я хотел бы предложить ремоделирования данные. Вы можете заменить атрибут species на отношение к объекту Species.

CoreData - это не реляционная база данных, а инфраструктура объектных графов. Если вы попытаетесь использовать его как реляционную базу данных, вы окажетесь в беспорядке.

+0

Благодарим вас за ответ Бенедикт. На самом деле я подумал о таком алгоритме, но в конечном итоге это не очень быстро на больших наборах данных. Возможно, я должен попытаться настроить его, но я подумал, что получить все в одном запросе будет действительно более эффективно. – lorenzo

Смежные вопросы