【发布时间】:2013-01-22 11:57:42
【问题描述】:
可能重复:
How can I find duplicate entries and delete the oldest ones in SQL?
由于更新工具错误,我有一个数据库有几千个重复项。我能够识别具有重复项的项目集合,但只需要删除最旧的条目,不一定是最低的 id。测试数据是这样的,正确的行有*
除了最近创建的行外,应删除具有重复标题且没有重复规则 ID 的文章。 (实际 id 列是 GUID,所以我不能假设自动递增)
Id Article id Rule Id Title Opened Date
-- ---------- ------- ----- -----------
1* 111 5 T1 2013-01-20
2 112 5 T1 2013-07-01
3* 113 6 T2 2013-07-01
4* 114 7 T2 2013-07-02
5 115 8 T3 2012-07-01
6 116 8 T3 2013-01-20
7* 117 8 T3 2013-01-21
表架构:
CREATE TABLE [dbo].[test_ai](
[id] [int] NOT NULL,
[ArticleId] [varchar](50) NOT NULL,
[ruleid] [varchar](50) NULL,
[Title] [nvarchar](max) NULL,
[AuditData_WhenCreated] [datetime] NULL,
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
测试数据插入
insert into test_ai (id, articleid, ruleid, title, auditdata_whencreated) values (1, 111, 5, 'test 1', '2013-01-20')
insert into test_ai (id, articleid, ruleid, title, auditdata_whencreated) values (2, 112, 5, 'test 1', '2012-07-01')
insert into test_ai (id, articleid, ruleid, title, auditdata_whencreated) values (3, 113, 6, 'test 2', '2012-07-01')
insert into test_ai (id, articleid, ruleid, title, auditdata_whencreated) values (4, 114, 7, 'test 2', '2012-07-02')
insert into test_ai (id, articleid, ruleid, title, auditdata_whencreated) values (5, 115, 8, 'test 3', '2012-07-01')
insert into test_ai (id, articleid, ruleid, title, auditdata_whencreated) values (6, 116, 8, 'test 3', '2013-01-20')
insert into test_ai (id, articleid, ruleid, title, auditdata_whencreated) values (7, 117, 8, 'test 3', '2013-01-21')
我当前的查询如下所示
select * from test_ai
where test_ai.id in
-- set 1 - all rows with duplicates
(select f.id
from test_ai as F
WHERE exists (select ruleid, title, count(id)
FROM test_ai
WHERE test_ai.title = F.title
AND test_ai.ruleid = F.ruleid
GROUP BY test_ai.title, test_ai.ruleid
having count(test_ai.id) > 1))
and test_ai.id not in
-- set 2 - includes one row from each set of duplicates
(select min(id)
from test_ai as F
WHERE EXISTS (select ruleid, title, count(id)
from test_ai
WHERE test_ai.title = F.title
AND test_ai.ruleid = F.ruleid
group by test_ai.title, test_ai.ruleid
HAVING count(test_ai.id) > 1)
GROUP BY title, ruleid
)
此 SQL 标识了一些应删除的行(第 2、6、7 行),但它确实选择了“打开日期”最旧的文章。 (应该删除第 2、5、6 行)我意识到我没有在语句中指定这一点,但正在努力解决如何添加最后一块。如果它导致我需要在多个重复项时多次运行以删除重复项的脚本,那不是问题。
实际的问题要复杂得多,但如果我能克服这一障碍,我将能够再次前进。感谢您的观看!
【问题讨论】:
-
我想这会对你有所帮助:jzinedine.me/post/30604785957/…
-
根据描述说你要删除的行,这个问题的标题不应该是“只保留最新的行”还是“删除除最新行之外的所有行”?目前标题与您的实际要求不符。
-
@AaronBertrand 同意,已调整。谢谢。
标签: sql sql-server tsql azure-sql-database