SQL:如何根据条件从 table 中删除行
SQL: How to delete rows from table based on a criteria
我有以下 table:
tbl
source type date
--- --- ---
google A 2010-02-25
google A 2013-04-11
facebook C 2008-10-22
facebook C 2007-01-28
我只想保留每个源的一个条目,条件是 select 具有 min(date) group by source
的源元组。 table 包含数百万条记录,我正在寻找一种删除冗余记录的有效方法。
在 MySQL 中,您可以使用 join
:
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;
我认为提高效率的唯一方法是将聚合结果存储在子查询中并向其添加索引。
我还可以补充一点,无论确定要删除的行的计算如何,删除 table 中的大量行效率低下。通常,我会推荐一个三步法:
- 编写查询以生成您想要的 table 并将结果存储在临时 table.
- 截断原来的table。
- 重新插入(少得多)数量的行。
在 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;
delete from t where date not in (select al.d from (select min(date) as d from t group by source )al);
将标识列添加到副本 table 作为序列号,作为行唯一标识符(自动递增升序):
alter table tbl add sno int identity(1,1)
此查询仅选择具有最小(日期)的非重复行:
(select min(date),sno From tbl group by source)
因此 "sno" 将等于“1”和“4”。
现在加入这个table,并删除重复的加入记录(t.sno为空)
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 的方法 3 改编的解决方案:LINK
我有以下 table:
tbl
source type date
--- --- ---
google A 2010-02-25
google A 2013-04-11
facebook C 2008-10-22
facebook C 2007-01-28
我只想保留每个源的一个条目,条件是 select 具有 min(date) group by source
的源元组。 table 包含数百万条记录,我正在寻找一种删除冗余记录的有效方法。
在 MySQL 中,您可以使用 join
:
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;
我认为提高效率的唯一方法是将聚合结果存储在子查询中并向其添加索引。
我还可以补充一点,无论确定要删除的行的计算如何,删除 table 中的大量行效率低下。通常,我会推荐一个三步法:
- 编写查询以生成您想要的 table 并将结果存储在临时 table.
- 截断原来的table。
- 重新插入(少得多)数量的行。
在 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;
delete from t where date not in (select al.d from (select min(date) as d from t group by source )al);
将标识列添加到副本 table 作为序列号,作为行唯一标识符(自动递增升序):
alter table tbl add sno int identity(1,1)
此查询仅选择具有最小(日期)的非重复行:
(select min(date),sno From tbl group by source)
因此 "sno" 将等于“1”和“4”。
现在加入这个table,并删除重复的加入记录(t.sno为空)
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 的方法 3 改编的解决方案:LINK