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; 

的唯一方法:

+0

该表是否有任何唯一的标识符(即主键,ID字段等)? –

+0

@ChrisJ nah,它没有。 – SaadH

在MySQL中,你可以使用join做到这一点并为其添加索引。

我还可以补充说,无论用于确定要删除的行的计算如何,都会以低效率删除表中的大量行。通常,我会推荐三步法:

  1. 编写查询以生成所需的表并将结果存储在临时表中。
  2. 截断原始表格。
  3. 重新插入(很多)较少的行数。

在Microsoft SQL中,您可以试试这个。

; 
WITH cte 
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY source, type 
             ORDER BY createdate) RN 
      FROM tbsource) 
DELETE FROM cte 
WHERE RN > 1; 
+0

这不是MySQL语法。 。 。在这么多方面。 –

+0

@戈登林诺夫,对不起。这个问题并不包含MySQL。 – Madhukar

+0

有一个mysql标签,但如果应该是这样的话,可能也应该在标题中。 – mikato

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) 

table

这个查询只选择非重复行最小(日期):

(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 

table3

解决方法:LINK