如何转换SQL语句"从不存在someID的TABLE中删除(通过property1,property2从Table组中选择someID)

nem*_*sys 4 sql core-data ios

我正在尝试将以下SQL语句转换为Core Data:

delete from SomeTable
where someID not in (
    select someID
    from SomeTable
    group by property1, property2, property3
)
Run Code Online (Sandbox Code Playgroud)

基本上,我想检索和删除表中可能的重复项,如果property1,property2和property3等于另一条记录,则记录被视为重复.

我怎样才能做到这一点?

PS:正如标题所说,我正在尝试将上述SQL语句转换为iOS核心数据方法,而不是试图改进,纠正或评论上述SQL,这是非常重要的.

谢谢.

Joh*_*ger 8

听起来你要求SQL来实现你的目标.您的起始查询将不会执行您所描述的内容,并且由于聚合子查询尝试选择不属于组的列的聚合子查询,因此大多数数据库根本不会接受它.

UPDATE

我最初认为请求是删除包含dupes的每个组的所有成员,并相应地编写代码.重新解释原始SQL就像MySQL一样,似乎目标是为每个组合保留一个元素(property1, property2, property3).我想这无论如何都更有意义.这是一种标准的方法:

delete from SomeTable st1
where someID not in (
    select min(st2.someId)
    from SomeTable st2
    group by property1, property2, property3
  )
Run Code Online (Sandbox Code Playgroud)

通过使用min()聚合函数来区分原始函数,someId以从每个组中选择要保留的特定值.这也应该有效:

delete from SomeTable st1
where someID in (
  select st3.someId
  from SomeTable st2
    join SomeTable st3
      on st2.property1 = st3.property1
        and st2.property2 = st3.property2
        and st2.property3 = st3.property3
  where st2.someId < st3.someId
)
Run Code Online (Sandbox Code Playgroud)

这两个查询将保留相同的行.我喜欢第二个更好,即使它更长,因为NOT IN操作员有点讨厌从大集合中选择少量元素.但是,如果您预计有足够的行来关注扩展,那么您应该尝试两者,并且可能会考虑优化(例如,索引(property1, property2, property3))和其他替代方案.

至于在核心数据调用方面写它,我认为你不能.核心数据确实支持分组,因此您可以编写在第一个备选方案中执行子查询的核心数据调用,并返回实体对象或其ID,按照描述进行分组.然后,您可以遍历组,跳过每个组的第一个元素,并为所有其他方法调用Core Data删除方法.详细信息超出了SO格式的范围.

我不得不说,虽然,在核心数据做这样的工作将是远远比直接在数据库中做更昂贵,无论是在时间和所需的内存.但是,直接在数据库中执行此操作对于诸如Core Data之类的ORM框架并不友好.这种事情是你通过使用ORM框架选择的权衡之一.

我建议你尽量避免这样做.定义一个唯一索引,SomeTable(property1, property2, property3)并执行您需要做的任何事情,以避免尝试创建重复项或从(失败)尝试中正常恢复.