NSPredicate SUBQUERY聚合

时间:2015-12-28 22:11:42

标签: core-data nspredicate

在我见过SUBQUERY的所有示例中,始终使用@count,例如,

SUBQUERY(employees, $e, $e.lastName == "Smith").@count > 0

所以我有三个非常密切相关的问题,这些问题最适合单个StackOverflow问题:

  1. 没有SUBQUERY的{​​{1}}是否有用?如果是这样,我还没有找到它。
  2. 是否可以将任何其他聚合与@count一起使用?如果是这样,我还没有能够让他们工作。 (见下文。)
  3. SUBQUERY究竟返回了什么?逻辑事物似乎是第一个参数类型的过滤集合。 (我在这里从概念上讲。显然SQL会有所不同,因为SQL调试很明显。)
  4. 这给了一个例外,我尝试过除SUBQUERY之外的所有其他聚合,这似乎表明不能使用其他聚合:

    @count

    (暂时暂且不谈这是否是表达此类事情的最佳方式。问题是SUBQUERY(employees, $e, $e.lastName == "Smith").@avg.salary > 75000 关于如何最好地制定查询。)

    Mundi有帮助地指出SUBQUERY的另一个用途是嵌套子查询。是的,我已经了解它们并使用过它们,但这个问题实际上是关于SUBQUERY结果。如果我们将SUBQUERY视为一个函数,除了使用SUBQUERY之外,它的结果是什么以及它可以以何种方式使用?

    更新

    感谢Mundi的研究,似乎像@count这样的聚合实际上与@avg一起使用,特别是对于内存过滤器,例如SUBQUERY,但不是当基础数据存储为filteredArrayUsingPredicate:时,使用核心数据。

1 个答案:

答案 0 :(得分:2)

  1. 是的,想一想嵌套的子查询。请参阅Dave DeLong的answer,用非常简单的术语解释子查询。
  2. 您的@avg不起作用的原因未知,因为它实际上应该适用于具有聚合函数所需的适当属性的任何集合。
  3. 参见1:SUBQUERY返回一个集合。
  4. 以下是实验的成绩单,证明子查询按预期工作。

    import UIKit
    import CoreData
    
    class Department: NSManagedObject {
        var name = "Department"
        var employees = Set<Person>()
    
        convenience init(name: String) {
            self.init()
            self.name = name
        }
    }
    
    class Person: NSManagedObject {
        var name: String = "Smith"
        var salary: NSNumber = 0
    
        convenience init(name: String, salary: NSNumber) {
            self.init()
            self.name = name
            self.salary = salary
        }
    }
    
    let department = Department()
    department.employees = Set ([
     Person(name: "Smith", salary: NSNumber(double: 30000)),
     Person(name: "Smith", salary: NSNumber(double: 60000)) ])
    
    
    let predicate = NSPredicate(format: "SUBQUERY(employees, $e, $e.name = %@).@avg.salary > 44000", "Smith")
    
    let depts = [department, Department()]
    let filtered = (depts as NSArray).filteredArrayUsingPredicate(predicate)
    

    上面只返回一个有两名员工的部门。如果我在谓词中替换45000,结果将不返回任何内容。