2011-02-01 16 views
6

So che posso usare @distinctUnionOfObjects per trovare qualcosa di simile a quanto segue in SQL:GROUP BY equivalente per Core Data

SELECT a_value 
FROM my_table 
GROUP BY a_value; 

Quello che sto cercando è tutti i dati restituiti in un array , non solo la matrice di valori che corrisponde al gruppo per espressione. In sostanza, sto cercando l'equivalente del seguente query SQL per i dati di base:

SELECT * 
FROM my_table 
GROUP BY a_value; 
+0

Fateci sapere se una risposta che ha aiutato. –

risposta

15

E 'analogico

SELECT 'Status', COUNT(*) FROM 'Records' GROUP BY 'Status':

NSFetchRequest* fetch = [NSFetchRequest fetchRequestWithEntityName:@"Record"]; 
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Record" 
              inManagedObjectContext:myManagedObjectContext]; 
NSAttributeDescription* statusDesc = [entity.attributesByName objectForKey:@"status"]; 
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"url"]; // Does not really matter 
NSExpression *countExpression = [NSExpression expressionForFunction: @"count:" 
                  arguments: [NSArray arrayWithObject:keyPathExpression]]; 
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; 
[expressionDescription setName: @"count"]; 
[expressionDescription setExpression: countExpression]; 
[expressionDescription setExpressionResultType: NSInteger32AttributeType]; 
[fetch setPropertiesToFetch:[NSArray arrayWithObjects:statusDesc, expressionDescription, nil]]; 
[fetch setPropertiesToGroupBy:[NSArray arrayWithObject:statusDesc]]; 
[fetch setResultType:NSDictionaryResultType]; 
NSError* error = nil; 
NSArray *results = [myManagedObjectContext executeFetchRequest:fetch 
                 error:&error]; 

Found here

+0

@ "Bimawa" Perché hai usato l'attributo "url" qui? – Developer

+0

@Developer // Non ha davvero importanza // Penso che sia un maleducato. – Bimawa

+0

Nel frammento sopra, 'url' è un campo nella tabella' Records'. Non c'è un modo per specificare 'COUNT (*)' con l'asterisco, ma questo è equivalente a 'COUNT (x)', dove 'x' è una qualsiasi colonna nella tabella. Questo è ciò che viene specificato in quella linea. – Demitri

-1

È possibile utilizzare Predicate Programming.

MODIFICA: Spiacenti, non è possibile utilizzare i predicati per Raggruppare almeno non direttamente. Ho appena letto sui riferimenti.

Limitazioni: non è possibile tradurre necessariamente query SQL "arbitrarie" in predicati o richieste di recupero. Non c'è modo, per esempio, per convertire un'istruzione SQL come

SELEZIONA t1.name, V1, V2

FROM table1 t1 JOIN (SELECT t2.name AS V1, count(*) AS V2 

    FROM table2 t2 GROUP BY t2.name as V) on t1.name = V.V1 
+0

Puoi essere più specifico? So che i predicati esistono, ma non so come potrebbero risolvere il mio problema. Come fornirebbero qualcosa come un gruppo di o distinto() in sql? – smtlaissezfaire

+0

Sì, ho notato anche questa affermazione.Sfortunatamente, non è del tutto chiaro * quali * sono questi limiti. La query fornita nella documentazione è molto più complessa (coinvolge un join) - Sto facendo una lettura straight table. – smtlaissezfaire

3

Si potrebbe provare a utilizzare un oggetto NSFetchedResultsController di fornire raggruppamento attraverso la costrutto sectionNameKeyPath nell'inizializzatore. Si noti che gli FRC devono essere principalmente utilizzati per accoppiarsi con una vista tabella, ma non è realmente necessario. In questo modo è possibile raggruppare i risultati con il tuo sectionNameKeyPath che potrebbe essere anche un attributo transitorio nel modello.

Come commento, non raccomanderei di pensare a Core Data in termini di un database, che non lo è. Core Data è stato creato per rendere più facile la persistenza e la gestione delle relazioni tra oggetti. Solo perché su iOS viene eseguito su SQLite non ne fa una sostituzione del database.

Riferimento: NSFRC Reference

0

trovo questo metodo (più o meno simile alla risposta accettata) di essere un po' più pulito e più facile capire. Questo è l'SQL equivalente a:

SELECT COUNT(*), a_value FROM my_table GROUP BY a_value;

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[MyTable className]]; 

// create expression for grouped column 
NSExpressionDescription *aValueDescription = [[NSExpressionDescription alloc] init]; 
aValueDescription.name = @"aValue"; // name of key in result dictionary 
aValueDescription.expression = [NSExpression expressionWithFormat:@"aValue"]; 
aValueDescription.expressionResultType = NSObjectIDAttributeType; 

// create expression for count 
NSExpressionDescription *countDescription = [[NSExpressionDescription alloc] init]; 
countDescription.name = @"count"; // name of dictionary key in result dictionary 
countDescription.expression = [NSExpression expressionWithFormat:@"[email protected]"]; 
countDescription.expressionResultType = NSInteger32AttributeType; 

// fill out fetch request 
fetchRequest.propertiesToGroupBy = @[@"aValue"]; 
fetchRequest.propertiesToFetch = @[aValueDescription, countDescription]; 
//fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"count" ascending:NO]]; // not sure why this crashes 
fetchRequest.resultType = NSDictionaryResultType; // required for "group by" requests 

NSError *error = nil; 
NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

La restituito results è un array di NSDictionary. Nota che la descrizione delle proprietà name può essere qualsiasi cosa tu voglia: sono solo i nomi delle chiavi nei dizionari restituiti. Si può aggiungere un predicato alla richiesta di recupero per filtrare le righe dalla tabella; questo codice restituisce tutte le righe.

punti bonus a chi mi può dire come fare il lavoro descrittore di sorta ...