我正在尝试将以下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,这是非常重要的.
谢谢.
听起来你要求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)并执行您需要做的任何事情,以避免尝试创建重复项或从(失败)尝试中正常恢复.
| 归档时间: |
|
| 查看次数: |
313 次 |
| 最近记录: |