Core data NSPredicate子查询聚合

Core data NSPredicate子查询聚合,core-data,nspredicate,Core Data,Nspredicate,在我看到的所有子查询示例中,总是使用@count,例如 SUBQUERY(employees, $e, $e.lastName == "Smith").@count > 0 因此,我有三个非常密切相关的问题,它们作为一个问题最有效: 没有@count的子查询是否有任何用处?如果是这样,我还没有找到它 任何其他聚合都可以与子查询一起使用吗?如果是这样,我就无法让他们工作。(见下文。) 子查询究竟返回什么?合乎逻辑的事情似乎是第一个参数类型的过滤集合。(我在这里是从概念上讲的。很明显,SQL

在我看到的所有
子查询
示例中,总是使用
@count
,例如

SUBQUERY(employees, $e, $e.lastName == "Smith").@count > 0
因此,我有三个非常密切相关的问题,它们作为一个问题最有效:

  • 没有
    @count
    子查询是否有任何用处?如果是这样,我还没有找到它
  • 任何其他聚合都可以与子查询一起使用吗?如果是这样,我就无法让他们工作。(见下文。)
  • 子查询
    究竟返回什么?合乎逻辑的事情似乎是第一个参数类型的过滤集合。(我在这里是从概念上讲的。很明显,SQL将有所不同,因为SQL调试非常清楚地表明了这一点。)
  • 这给出了一个例外,除了
    @count
    之外,我尝试过的所有其他聚合都是例外,这似乎表明没有其他聚合可以使用:

    SUBQUERY(employees, $e, $e.lastName == "Smith").@avg.salary > 75000
    
    (让我们暂且不谈这是否是表达这种事情的最佳方式。问题是关于
    子查询
    而不是如何最好地表述查询。)

    Mundi很有帮助地指出,
    子查询
    的另一个用途是嵌套子查询。是的,我知道并使用过它们,但这个问题实际上是关于
    子查询的结果。如果我们将
    子查询
    视为一个函数,那么它的结果是什么?除了使用
    @count
    之外,还可以以什么方式使用它

    更新 由于Mundi的研究,似乎像
    @avg
    这样的聚合实际上可以与
    子查询
    一起工作,特别是与内存中的筛选器(如
    FilteredarrayingPredicate:
    )一起工作,但当底层数据存储为
    NSSQLiteStoreType
    时,则不能与核心数据一起工作

  • 是的,考虑嵌套子查询。请参阅DaveDelong的文章,它用非常简单的术语解释了子查询
  • 您的
    @avg
    不起作用的原因是未知的,因为它实际上应该作用于具有聚合函数所需的适当属性的任何集合
  • 请参见1.:子查询返回集合 下面是一个实验的记录,该实验证明子查询按预期工作

    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)
    
    导入UIKit
    导入CoreData
    班级部门:NSManagedObject{
    var name=“部门”
    var employees=Set()
    便利初始化(名称:字符串){
    self.init()
    self.name=名称
    }
    }
    课程负责人:NSManagedObject{
    变量名称:String=“Smith”
    var工资:NSNumber=0
    便利初始化(名称:字符串,工资:NSNumber){
    self.init()
    self.name=名称
    薪水
    }
    }
    let department=department()
    department.employees=Set([
    人员(姓名:“史密斯”,工资:NSNumber(双倍:30000)),
    人员(姓名:“史密斯”,工资:NSNumber(双倍:60000)))
    let predicate=NSPredicate(格式:“子查询(雇员,$e,$e.name=%@)。@avg.salary>44000”,“Smith”)
    让部门=[部门,部门()]
    let filtered=(depts as NSArray)。filteredarrayingpredicate(谓词)
    

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

    如果
    @count
    聚合可以应用于
    子查询
    ,它是否已经是一个集合?为什么我可以说
    employees.@count
    employees.@avg.salary
    SUBQUERY()。@count
    而不是
    SUBQUERY()。@avg.salary
    ?回答你的问题:显然,
    avg
    aggregate函数需要从被查询的集合中获得更多信息,而不仅仅是
    count
    。那么您是说
    子查询的结果是count,而不是筛选的集合?这似乎没有多大意义。如果这是真的,我们会说
    子查询(…)>0
    ,而不是
    子查询(…)。@count>0
    。我想你和我对
    子查询
    一定有不同的思维模式。对我来说,它看起来非常像Haskell或Python中的列表理解,尽管语法更简单。所以,它应该返回一个过滤实体的集合。如果我可以说
    employees.@avg.salary
    ,我应该可以说
    子查询(employees,…。@avg.salary
    ,但我不能。我怀疑这只是将谓词翻译成底层语言(如SQL或XPath)的技术限制。经过一番实验,我得出结论,你最初的假设是正确的。您得到的错误一定是由于其他原因造成的。我修改了我的答案,并演示了第1点和第2点(我想还有第3点)。