SQL:如何删除基于一个条件,从表中的行
问题描述:
我有如下表:SQL:如何删除基于一个条件,从表中的行
tbl
source type date
--- --- ---
google A 2010-02-25
google A 2013-04-11
facebook C 2008-10-22
facebook C 2007-01-28
我想只保留每个源的一个条目,而标准是选择具有min(date) group by source
源元组。该表由数百万条记录组成,我正在寻找删除多余记录的有效方法。 - 离手 - 这是我能想到的,使这个更有效的是将聚集结果存储在一个子查询
delete t
from t join
(select source, min(date) as mindate
from t
group by source
) tt
on t.source = tt.source
where t.date > tt.mindate;
的唯一方法:
答
在MySQL中,你可以使用join
做到这一点并为其添加索引。
我还可以补充说,无论用于确定要删除的行的计算如何,都会以低效率删除表中的大量行。通常,我会推荐三步法:
- 编写查询以生成所需的表并将结果存储在临时表中。
- 截断原始表格。
- 重新插入(很多)较少的行数。
答
delete from t where date not in (select al.d from (select min(date) as d from t group by source)al);
+0
谢谢你的这段代码,它可能会提供一些有限的即时帮助。通过展示*为什么*这是一个很好的解决方案,并且使它对未来的读者更有用,一个正确的解释[将大大提高](// meta.stackexchange.com/q/114762)其长期价值其他类似的问题。请[编辑]你的答案以添加一些解释,包括你所做的假设。 –
答
到重复表添加标识列充当行唯一标识符(自动增量升序)序列号:
alter table tbl add sno int identity(1,1)
这个查询只选择非重复行最小(日期):
(select min(date),sno From tbl group by source)
所以“sno”将等于“1”和“4”。
现在有了这个表连接,并删除加入该的记录是重复的(t.sno为null)从这个链接的方法3调整
delete E from tbl E
left join
(select min(date),sno From tbl group by source) T on E.sno=T.sno
where T.sno is null
解决方法:LINK
该表是否有任何唯一的标识符(即主键,ID字段等)? –
@ChrisJ nah,它没有。 – SaadH