【问题标题】:Update one entry of each unique Record in SQL Server更新 SQL Server 中每个唯一记录的一个条目
【发布时间】:2013-01-27 16:32:34
【问题描述】:

我有一个包含用户名和已删除状态的表。重复的用户名已删除状态组合是可能的。如果一个用户名有多个条目的已删除状态为 1,那么我需要将每个用户名的一个条目的已删除状态更新为 0。

考虑以下数据:

Name  EmpId  Deleted
--------------------
A     01     1
A     01     1
B     02     1
B     02     0
C     03     1

要求:名称 A 和 C 的一项应更新为 0(已删除状态)。

declare @testTable table (Name varchar(10), EmpId varchar(10), Deleted tinyint)

insert into @testTable
select 'A', '01', 1 UNION ALL
select 'A', '01', 1 UNION ALL
select 'B', '02', 1 UNION ALL
select 'B', '02', 0 UNION ALL
select 'C', '03', 1

select * from @testTable

【问题讨论】:

  • 你自己尝试过什么吗?
  • 我无法为此编写更新,因此我为每个状态不为 0 的用户名插入了一个新条目。
  • 您写道:“多个条目的已删除状态为 1”,然后您写道:“要求:名称 A 和 C 的一个条目应更新为 0(已删除状态)。”为什么要删除C?在您的示例中,我们只有一个名称为“C”的条目
  • @RomanBadiornyi:我发现了同样的问题,自相矛盾。我在下面回答仅更新重复项。
  • 使用此表中的 UNIQUE ID 列,您的生活会轻松很多。

标签: sql sql-server sql-server-2005 sql-update


【解决方案1】:

试试这个;

;with cte as
(
  select name, empId, deleted, 
         row_number() over (partition by name, empId order by deleted desc) rn
  from T
)
Update cte set deleted = 0
where rn <> 1 and deleted = 1

SQL FIDDLE DEMO

【讨论】:

  • 我认为第 5 行,即 C 不会得到更新。请确认。
  • 在您给定的数据示例中,CNOT 重复的,这就是原因。
  • 是的,描述并不完美。我还需要更新 C 的记录。无论如何都是好的逻辑。
  • 那么,更新的逻辑是什么?如果您只需要更新 C 而不管任何逻辑,那么您可以将 Or name = 'C' 添加到 Where 子句
【解决方案2】:

这是一种方法:

with toupdate as (
      select t.*,
             row_number() over (partition by name, deleted order by deleted) as seqnum
      from t
     )
update toupdate
    set deleted = 0
    where deleted = 1 and seqnum = 1

【讨论】:

    【解决方案3】:

    SqlFillde demo

    with t1 as 
    (
    select *, ROW_NUMBER() OVER 
               (PARTITION BY EMPID order by deleted) as rn
           from testtable
    )
    update t1 set deleted=0 where rn=1 and deleted=1
    

    【讨论】:

      【解决方案4】:
      declare @testTable table 
      (
          Name varchar(10), 
          EmpId varchar(10), 
          Deleted tinyint
      )
      
      insert into @testTable
      select 'A', '01', 1 UNION ALL
      select 'A', '01', 1 UNION ALL
      select 'A', '01', 1 UNION ALL
      select 'B', '02', 1 UNION ALL
      select 'B', '02', 0 UNION ALL
      select 'B', '02', 0 UNION ALL
      select 'C', '03', 1
      
      select * from @testTable
      update @testTable set deleted=1
      BEGIN
      with t1 as 
      (
      select *, ROW_NUMBER() OVER 
                 (PARTITION BY EMPID order by deleted) as rn
             from @testTable
      )
      update t1 set deleted=0 where rn=1 and deleted=1
      END
      select * from @testTable
      

      【讨论】:

        【解决方案5】:
            UPDATE A
            SET Deleted = (CASE WHEN RowNum = 1 THEN 0 ELSE Deleted END)
            FROM
            (SELECT *,ROW_NUMBER() OVER(PARTITION BY Name ORDER BY Deleted) AS RowNum
            FROM @testTable A WHERE Name NOT IN (SELECT Name FRom @testTable B Where Deleted=0)
            ) A
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-10-04
          • 1970-01-01
          • 2021-01-26
          • 1970-01-01
          • 2012-09-29
          • 1970-01-01
          • 2014-06-01
          相关资源
          最近更新 更多