NSPredicate SUBQUERY 聚合
NSPredicate SUBQUERY aggregates
在我见过的所有 SUBQUERY
示例中,总是使用 @count
,例如
SUBQUERY(employees, $e, $e.lastName == "Smith").@count > 0
所以我有三个非常密切相关的问题,它们作为一个 Whosebug 问题最有效:
- 没有
@count
,SUBQUERY
有什么用?如果有,我还没找到。
- 是否可以将任何其他聚合与
SUBQUERY
一起使用?如果是这样,我无法让他们工作。 (见下文。)
SUBQUERY
return 究竟是什么?合乎逻辑的东西似乎是第一个参数类型的过滤集合。 (我在这里是从概念上讲的。显然 SQL 会有所不同,因为 SQL 调试显示得非常清楚。)
这给出了一个例外,就像我尝试过的所有其他聚合一样,除了 @count
,这似乎表明没有其他聚合可以使用:
SUBQUERY(employees, $e, $e.lastName == "Smith").@avg.salary > 75000
(让我们暂时搁置这是否是表达这种事情的最佳方式。问题是关于 SUBQUERY
, 而不是 关于如何最好地表述查询。)
Mundi 指出 SUBQUERY
的另一个用途是嵌套子查询。是的,我知道它们并使用过它们,但这个问题实际上是关于 SUBQUERY
的 result。如果我们将 SUBQUERY
视为一个函数,除了 @count
?
之外,它的结果是什么以及它可以用什么方式使用
更新
感谢 Mundi 的研究,@avg
之类的聚合似乎确实适用于 SUBQUERY
,尤其是内存中过滤器,例如 filteredArrayUsingPredicate:
,但不适用于 Core底层数据存储为 NSSQLiteStoreType
.
时的数据
- 是的,想想嵌套子查询。请参阅 Dave DeLong 的 answer,它用非常简单的术语解释了子查询。
- 您的
@avg
不起作用的原因尚不清楚,因为它实际上应该适用于具有聚合函数所需的适当属性的任何集合。
- 参见 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 什么都没有。
在我见过的所有 SUBQUERY
示例中,总是使用 @count
,例如
SUBQUERY(employees, $e, $e.lastName == "Smith").@count > 0
所以我有三个非常密切相关的问题,它们作为一个 Whosebug 问题最有效:
- 没有
@count
,SUBQUERY
有什么用?如果有,我还没找到。 - 是否可以将任何其他聚合与
SUBQUERY
一起使用?如果是这样,我无法让他们工作。 (见下文。) SUBQUERY
return 究竟是什么?合乎逻辑的东西似乎是第一个参数类型的过滤集合。 (我在这里是从概念上讲的。显然 SQL 会有所不同,因为 SQL 调试显示得非常清楚。)
这给出了一个例外,就像我尝试过的所有其他聚合一样,除了 @count
,这似乎表明没有其他聚合可以使用:
SUBQUERY(employees, $e, $e.lastName == "Smith").@avg.salary > 75000
(让我们暂时搁置这是否是表达这种事情的最佳方式。问题是关于 SUBQUERY
, 而不是 关于如何最好地表述查询。)
Mundi 指出 SUBQUERY
的另一个用途是嵌套子查询。是的,我知道它们并使用过它们,但这个问题实际上是关于 SUBQUERY
的 result。如果我们将 SUBQUERY
视为一个函数,除了 @count
?
更新
感谢 Mundi 的研究,@avg
之类的聚合似乎确实适用于 SUBQUERY
,尤其是内存中过滤器,例如 filteredArrayUsingPredicate:
,但不适用于 Core底层数据存储为 NSSQLiteStoreType
.
- 是的,想想嵌套子查询。请参阅 Dave DeLong 的 answer,它用非常简单的术语解释了子查询。
- 您的
@avg
不起作用的原因尚不清楚,因为它实际上应该适用于具有聚合函数所需的适当属性的任何集合。 - 参见 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 什么都没有。