9

Need help.

I have 4 fields in my table:

  • email
  • message
  • read
  • date_received

I want to select the email , message (recent) ,date_received, and the sum of unread messages

Here's my expected result:

test@email.com | Test Message | 2015-02-27 | 28 test2@email.com | Test Message2 | 2015-02-29 | 2

Here's my current code:

let fetchRequest:NSFetchRequest = NSFetchRequest()

if let entityDescription:NSEntityDescription = NSEntityDescription.entityForName("Message", inManagedObjectContext: managedObjectContext){
    fetchRequest.entity = entityDescription
}

fetchRequest.propertiesToFetch = ["email","message","read","date_received"]
fetchRequest.propertiesToGroupBy = ["email"]
fetchRequest.resultType = .DictionaryResultType
fetchRequest.returnsObjectsAsFaults = false

let items:NSArray = managedObjectContext .executeFetchRequest(fetchRequest, error: nil)!

Output:

20 18:24:51.639 JPtxt[33368:1345477] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'SELECT clauses in queries with GROUP BY components can only contain properties named in the GROUP BY
Bista
  • 7,869
  • 3
  • 27
  • 55
jdoe
  • 97
  • 1
  • 4
  • Please enable [SQL query logging](http://stackoverflow.com/questions/6428630/xcode4-and-core-data-how-to-enable-sql-debugging) and post the resulting query. – ctietze Mar 20 '15 at 12:05
  • I think your problem is the same as this one: http://stackoverflow.com/questions/20995405/how-to-apply-group-by-clause-in-core-data – sheisd Mar 20 '15 at 12:48

2 Answers2

1

Just fetch the messages with the usual NSManagedObjectResultType (you don't need to specify that). Then just get the count via a KVC (both solutions tested):

let count = (result.filteredArrayUsingPredicate(
   NSPredicate(format: "read = NO")) as NSArray).count

A non-standard but perhaps more concise way is to exploit the fact that booleans are stored as ones and zeros

let count = result.count - result.valueForKeyPath("@sum.read")!.integerValue
Mundi
  • 79,884
  • 17
  • 117
  • 140
0

The error you are getting, is about SQL rules. That said SQL states that if you want to group by ["email"] you can't request other properties, unless you wanted to group by them as well. An example would be if you wanted to count messages by, let's say, "gender" and "age", not the case.

    fetchRequest.propertiesToFetch = ["email"]

However, you can and will need a predicate on the "read" property to say that you want only unread messages. A predicate is usually more performant than filtering after the request is made:

    fetchRequest.propertiesToGroupBy = ["email"]
    fetchRequest.predicate = NSPredicate(format: "read = NO")
Rodrigo Fava
  • 318
  • 3
  • 12