0

仅从表中查找和更新重复记录的最佳方法是什么。例如,以下记录被认为是重复的,只有 ID 使它们唯一。我需要将记录 2 和 3 的活动字段更新为 0 而不是 1,并将日期设置为 getdate()。我需要不更新这些重复项(ID 1)的第一个实例。我有一个表有数千个这种情况,需要停用重复记录。

有任何想法吗?

acct_plan 表:

ID  act   plan   active   date   
1   123   blue   1        NULL    
2   123   blue   1        NULL  
3   123   blue   1        NULL

提前感谢您的帮助!:)

4

4 回答 4

5

对于此类问题,我喜欢使用以下 CTE:

with toupdate as (
      select ap.*,
             row_number() over (partition by act, plan, active, date
                                order by id
                               ) as seqnum
      from acct_plan
     )
update toupdate
    set date = getdate(),
        active = 0
    where seqnum > 1;

这是 SQL Server 支持的语法,但通常不适用于其他数据库。

于 2013-05-31T21:47:18.283 回答
3
update t1 
set t1.active=0,
t1.date = GETDATE()
from acct_plan t1
where t1.ID NOT in (select MIN(t2.Id) from acct_plan t2
                    GROUP BY t2.act, t2.[plan], t2.active, t2.date);

SqlFiddle

顺便说一句,plan是 sql server 2005 中的保留关键字。将保留关键字用于对象名称总是一个坏主意......

于 2013-05-31T21:45:49.770 回答
1

这类似于@Gordon 的查询。只是为了向您展示另一种实现方式(SQL 2005 及更高版本):

UPDATE A
SET
   A.active = 0,
   A.date = GetDate()
FROM
   (
      SELECT A.*, MinID = Min(A.ID) OVER (PARTITION BY A.act, A.[plan], A.date)
      FROM dbo.acct_plan A
      WHERE A.active = 1
   ) A
WHERE
   A.ID > A.MinID
;

在 SQL Fiddle 上查看现场演示

我还将呼应 Raphaël Althaus,它plan是 SQL Server 中的保留关键字,不应用于列名。您可以看到我的查询必须将单词括在方括号中才能解析和运行——这不是理想的情况。

于 2013-05-31T22:27:17.147 回答
0

这对我有用:

update acct_plan set active = 0, date = getdate()
where ID in 
(select ID FROM  acct_plan 
LEFT OUTER JOIN
                 (SELECT    MIN(ID) AS RowId, act, plan, active, date
                            FROM acct_plan
                            GROUP BY act, plan, active, date) 
                 AS KeepRows ON acct_plan.ID = KeepRows.RowId
WHERE (KeepRows.RowId IS NULL))
于 2013-05-31T21:59:26.303 回答