9

How do I create a predicate that can fetch: all questions does not contain answer.correct = "1".

The following predicate doesn't work if the returned array contain "0" and "1":

[NSPredicate predicateWithFormat:@"NONE answers.correct IN %@", [NSArray arrayWithObject:@"1"]];

Also tried with NOT (ANY ...) : same result

Is this a Bug?

DataModel

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
JGLstudio
  • 130
  • 1
  • 5

1 Answers1

23

Short answer: To get all objects that do not have any "answer" with "correct == 1", use the following SUBQUERY:

[NSPredicate predicateWithFormat:@"SUBQUERY(answers, $a, $a.correct == 1).@count == 0"]

Explanation: Both predicates

[NSPredicate predicateWithFormat:@"NONE answers.correct == 1"]
[NSPredicate predicateWithFormat:@"NOT (ANY answers.correct == 1)"]

should work (as I understand the NOT and ANY keywords) but they don't. They return the same result set as

[NSPredicate predicateWithFormat:@"ANY answers.correct != 1"]

as can be seen by setting the launch argument -com.apple.CoreData.SQLDebug 3 and inspecting the SQL select statements.

This seems like a Core Data bug to me. Using the SUBQUERY is a workaround for that problem.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • This does not give me what I need, if a question that have 2 userAnswers, one with correct=1 and another with correct=0. This question is still be selected. I need only questions that has not being answered correctly. – JGLstudio Jan 24 '13 at 01:38
  • @JglStudioUs: Strange. I will check that later when I am at my computer. Is the "correct" attribute stored as string or number? – Martin R Jan 24 '13 at 06:42
  • @JglStudioUs: You are right, the predicate does not work as I would have expected (I haven't yet figured out why). The following (slightly more complex) predicate worked in my test: `@"SUBQUERY(answers, $a, $a.correct == 1).@count == 0"`, can you try that? – Martin R Jan 24 '13 at 08:30
  • Martin: @"SUBQUERY(answers, $a, $a.correct == 1).@count == 0" is working for me. – JGLstudio Jan 24 '13 at 17:09
  • @JglStudioUs: OK. I was quite sure that my answer is correct, but this seems like a Core Data bug to me. I will update the answer accordingly. – Martin R Jan 24 '13 at 17:12
  • You should move your correct answer above your wrong one! Save folk some time...like me! ;-) Thanks for figuring this out though, excellent work. – malhal Apr 07 '16 at 23:55
  • @MartinR Thanks a ton !!!! kept breaking my head with `NONE` / `NOT ANY`. Has a bug been filed with Apple ? – user1046037 May 22 '18 at 12:06
  • @user1046037: I don't know (I didn't yet). – But anyway: If you are effected by the problem then you can file your own bug report. – Martin R May 22 '18 at 12:10
  • What I've found is that ANY / NONE don't work unless there's at least one object in the collection @martinr – atlex2 May 26 '20 at 00:36
  • Is it possible that this happens to objects that are faulted. For me, some objects were filtered by the predicate and some were not, seemingly randomly. Maybe the SUBQUERY forces the related object faults to be fired. – Carson Holzheimer Feb 03 '21 at 05:29
  • I would upvote this answer 10 more times if I could. Thank you! Excellent detective work and great work around! I checked out the underlying sql queries as you suggested and the sql generated for the NOT ANY predicate is definitely flawed. – Kenny Wyland May 07 '21 at 20:55