NSPredicate SUBQUERY 聚合

NSPredicate SUBQUERY aggregates

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

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

所以我有三个非常密切相关的问题,它们作为一个 Whosebug 问题最有效:

  1. 没有@countSUBQUERY有什么用?如果有,我还没找到。
  2. 是否可以将任何其他聚合与 SUBQUERY 一起使用?如果是这样,我无法让他们工作。 (见下文。)
  3. SUBQUERY return 究竟是什么?合乎逻辑的东西似乎是第一个参数类型的过滤集合。 (我在这里是从概念上讲的。显然 SQL 会有所不同,因为 SQL 调试显示得非常清楚。)

这给出了一个例外,就像我尝试过的所有其他聚合一样,除了 @count,这似乎表明没有其他聚合可以使用:

SUBQUERY(employees, $e, $e.lastName == "Smith").@avg.salary > 75000

(让我们暂时搁置这是否是表达这种事情的最佳方式。问题是关于 SUBQUERY 而不是 关于如何最好地表述查询。)

Mundi 指出 SUBQUERY 的另一个用途是嵌套子查询。是的,我知道它们并使用过它们,但这个问题实际上是关于 SUBQUERYresult。如果我们将 SUBQUERY 视为一个函数,除了 @count?

之外,它的结果是什么以及它可以用什么方式使用

更新

感谢 Mundi 的研究,@avg 之类的聚合似乎确实适用于 SUBQUERY,尤其是内存中过滤器,例如 filteredArrayUsingPredicate:,但不适用于 Core底层数据存储为 NSSQLiteStoreType.

时的数据
  1. 是的,想想嵌套子查询。请参阅 Dave DeLong 的 answer,它用非常简单的术语解释了子查询。
  2. 您的 @avg 不起作用的原因尚不清楚,因为它实际上应该适用于具有聚合函数所需的适当属性的任何集合。
  3. 参见 1.: SUBQUERY return 是一个集合。

这是证明子查询按预期工作的实验记录。

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)

以上return正好是一个有两名员工的部门。如果我在谓词中替换 45000,结果将 return 什么都没有。