【问题标题】:Update one of 2 duplicates in an sql server database table更新 sql server 数据库表中的 2 个重复项之一
【发布时间】:2021-08-06 18:15:14
【问题描述】:

我有一个表,其中有一列具有重复值。我想更新 2 个重复值之一,例如 row1 = tomrow2 = tom.. 我想向其中一个添加 1 或 a ,这将用于同一列中的许多其他重复项。基本上只需在每个重复项中添加一个数字或字母,这样就不会再有重复项了。

我得到了这个查询,它将更新所有重复项,但不会更新其中一个。有人可以帮忙吗?

UPDATE Table1
   SET Column1 = 'a'
 WHERE exists
       (SELECT Column1 , COUNT(Column1 )
FROM Clients
GROUP BY Column1 
HAVING ( COUNT(Column1 ) > 1)
)

【问题讨论】:

  • 如果它是重复记录,为什么需要保留它?这样做有什么具体原因吗?
  • 您的架构是什么样的?有什么主键可以使用吗?
  • 我需要它,因为它是有价值的信息,我不想删除它们中的任何一个。只是想将它们区分开来进行数据分析。是的,我有一个作为主键的 ID。

标签: sql sql-server


【解决方案1】:

CTEPARTITION BY 试试这个

;WITH cte AS
(
  SELECT
      ROW_NUMBER() OVER(PARTITION BY Column1  ORDER BY Column1 ) AS rno,
      Column1 
  FROM Clients
)

UPDATE cte SET Column1 =Column1 +' 1 '
WHERE rno=2

【讨论】:

  • 您不想更新 Clients 表而不是“cte”(这只是暂时的)吗? PostgreSQL 拒绝了这种语法。我最终得到的结果更像:UPDATE Clients SET Column1 = Column1 + '1' WHERE cte.rno = 2;
【解决方案2】:

我认为这个简单的更新正是您想要的;

UPDATE Table1 SET Column1=Column1+CAST(id AS VARCHAR)
WHERE id NOT IN (
  SELECT MIN(id) 
  FROM Table1
  GROUP BY Column1
);

输入:

(1,'A'),
(2,'B'),
(3,'A'),
(4,'C'),
(5,'C'),
(6,'A');

输出:

(1,'A'),
(2,'B'),
(3,'A3'),
(4,'C'),
(5,'C5'),
(6,'A6');

An SQLfiddle to test with.

【讨论】:

    【解决方案3】:

    我认为您可以使用 TOP() 运算符代替 row_number() 方法,它将帮助您以简单的方式更新一个

    UPDATE TOP ( 1 )Table1 SET Column1 = 'a';
    

    【讨论】:

    • 请确保您的答案。通常,答案中的“我认为”会降低您的答案被选中的可能性。
    • 这是最好的答案。它使用应用程序中的正确工具,这不是解决方法。 (此外,它有效 - 它刚刚解决了我遇到的问题。)
    【解决方案4】:

    假设Table1,包含以下信息:

    Column1      
    ========  
    tom        
    john   
    jack    
    tom     
    james
    jane 
    

    请注意,第一行和第四行是相同的。这是UPDATE 命令,用于仅更改其中一个名称。

    UPDATE Table1 AS t1
       SET Column1 = 'jennifer'
     WHERE rrn(t1) =
           (SELECT MAX(rrn(t2))
              FROM Table1 AS t2
             WHERE Column1 = 'tom')
    

    结果是

    Column1      
    ========  
    tom        
    john   
    jack    
    jennifer
    james
    jane 
    

    使用RRN 函数可以更新最后一次出现的重复记录

    【讨论】:

    • 这会将任何 tom 更改为我不想要的。我有一个大数据,该列有很多重复项。我想要的只是在其中一个副本的末尾添加一个字母或递增的数字,而不是手动执行。
    • 更新后拒绝接受AS t1..这是为什么?
    【解决方案5】:

    如果我们有这个条件:

    SELECT Column1 FROM Clients ORDER BY Column1
    
    Column1
    **********
    Jhon
    Jhon
    Mike
    Mike
    Mike
    Robert
    

    即使Column1 被复制了 n 次,这也可以工作,它会将行号附加到除第一行之外的每个重复行,试试这个:

    BEGIN 
    
    ;WITH CTE AS 
    (
        SELECT 
            ROW_NUMBER() OVER (PARTITION BY Column1 ORDER BY Column1) AS ROWNUMBER,
            Column1
        FROM Clients
    )
    
    UPDATE CTE 
    SET Column1 = CONCAT(Column1, ' ', (ROWNUMBER - 1))
    WHERE ROWNUMBER > 1
    
    SELECT Column1 FROM Clients ORDER BY Column1
    
    END 
    

    结果:

    Column1
    ***********
    Jhon
    Jhon 1
    Mike
    Mike 1
    Mike 2
    Robert
    

    【讨论】:

      【解决方案6】:

      试试这个

      with test as 
      (
         select ROW_NUMBER() over (order by salary)rr, salary , emp_no 
         from salary
      )update test set emp_no=10007 where emp_no='10002'  and rr=3
      

      【讨论】:

        【解决方案7】:

        试试这个朋友

        UPDATE Table1 
        SET Column1 = column1 +'a'   
        WHERE exists(
                select row 
                from (
                    SELECT 
                        Column1 , 
                        Row_Number() over(Partition by Column1 order by Column1) as row 
                    FROM Clients
                ) as subquery 
                where subquery.row = 2
            )
        

        【讨论】:

        • 它正在更新所有行。我的意思是所有重复的行
        【解决方案8】:

        我不得不将 with 放在 from 中,因为我的 sql 开发人员不喜欢更新 with 从 Nithesh 的答案中复制

        它最终看起来像这样:

        UPDATE Clients 
        SET Column1 = 'a'
        WHERE ColumnID IN (select ColumnID from 
         (  
         SELECT
               row_number() OVER(PARTITION BY Column1  ORDER BY Column1 ) AS rno,
               ColumnID FROM Clients
         )
                           where rno=2   
                          )
        

        【讨论】:

          【解决方案9】:
          update wmwhse1.sku
          set descr= concat (descr,'.')
          where exists
          (select SKU,count (DESCR)
          from wmwhse1.sku
          group by descr
          having (count (DESCR)>1))
          

          当我运行此脚本时,所有 sku 描述都会更新。

          输出:应该只影响 1 行

          【讨论】:

            【解决方案10】:

            我找到了这个解决方案:

            我的表 devices 已经有数据并且“serial”列应该是唯一的。 “id”是主键。在原始值之后连接一个随机的 6 位值。

            UPDATE devices 
            SET serial=CONCAT(serial,'_',LPAD(FLOOR(RAND() * 999999.99), 6, '0'))    
                where id in 
                (select * FROM( 
                    SELECT d1.id as id 
                    FROM devices as d1, devices as d2 
                    WHERE d1.id <> d2.id and d1.serial=d2.serial) as subdevices
                )
            

            【讨论】:

              【解决方案11】:

              使用子查询可能有效:

              UPDATE table1
              SET STATUS = 'F'
              WHERE column1= 
                 (SELECT (column1)
                  FROM table1
                  GROUP BY column1 
                  HAVING (COUNT(column1 ) > 1))
              

              【讨论】:

              • 欢迎来到 Stack Overflow。请提供一些解释如何解决提问者的问题,以便未来的用户可以从您的回答中学习。
              【解决方案12】:

              免责声明:

              1. 查询语言:Microsoft SQL 查询
              2. 在 cmets 中明确了步骤,例如:--

              问题:UPDATE last Id with 'D' where year, month is duplicate memberwise。

              -- Sample Table Creation
              
              DECLARE @TempTable TABLE
              ( Id INT IDENTITY (1, 1) NOT NULL, MemberId INT, for_year INT, for_month INT, for_status CHAR(1) )
              
              -- Sample Insert
              INSERT INTO @TempTable
              SELECT '2', '2077', '11', 'A' UNION ALL
              SELECT '2', '2077', '12', 'A' UNION ALL
              SELECT '2', '2077', '12', 'A' UNION ALL
              SELECT '3', '2077', '11', 'A' UNION ALL
              SELECT '3', '2077', '12', 'A' UNION ALL
              SELECT '3', '2077', '12', 'A' UNION ALL
              SELECT '77', '2076', '10', 'A' UNION ALL
              SELECT '77', '2076', '11', 'A' UNION ALL
              SELECT '77', '2076', '12', 'A'
              
              -- where expectation meets reality :) -- logic / main query
              UPDATE @TempTable SET for_status = 'D' WHERE Id IN 
              (
              SELECT MAX(Id) FROM @TempTable GROUP BY MemberId, for_year, for_month HAVING COUNT(*)>1
              )
              
              -- Sample Select
              SELECT * FROM @TempTable
              

              【讨论】:

              • 欢迎来到 StackOverflow。虽然此代码可能会解决问题,但包括解释如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释并说明适用的限制和假设。
              【解决方案13】:

              我找到了一种解决方案:

              在表格中插入一个虚拟列

              更新列中的值并给出随机值

              使用该虚拟列的值更新该行并删除该列。

              Step 1 :
              Alter table table_name
              ADD column dummy_column
              
              Step 2:
              Update table_name
              SET dummy_column = (RAND() * 10) 
              where duplicate_column = duplicate_value
              
              Step 3:
              Update table_name
              SET duplicate_column = new_value
              where dummy_column = random_value
              
              Step 4:
              Alter table table_name
              drop column dummy_column
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-11-12
                • 1970-01-01
                • 2018-06-17
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-02-16
                • 1970-01-01
                相关资源
                最近更新 更多