如何在mysql中将重复行更改为唯一值?

时间:2012-06-08 23:06:36

标签: mysql unique

我有一个包含大约1M记录的数据库表。我需要在此表中找到所有重复的名称,并使它们唯一。

例如......

Id   Name
-----------
1    A
2    A
3    B
4    C
5    C

应改为......

Id   Name
-----------
1    A-1
2    A-2
3    B
4    C-1
5    C-2

使用mysql查询或过程是否有效的方法?

提前致谢!

3 个答案:

答案 0 :(得分:2)

这有点棘手..我在我的本地主机上进行了测试,它可以满足您的需求..如果您有任何疑问,请告诉我。 SQL FIDDLE

UPDATE temp t1, 
(
    SELECT 
        id as unique_id, 
        new_name 
    FROM(
        SELECT
          id,
          IF(@ROW = Name, @COUNT, @COUNT := 1),
          CONCAT(Name, ' - ', @COUNT) AS new_name,
          @ROW := Name,
          @COUNT := @COUNT + 1
        FROM temp
        JOIN (SELECT @COUNT := 0, @ROW := "") AS t
        WHERE Name IN(SELECT Name FROM temp
        GROUP BY Name
        HAVING COUNT(Name) > 1)
    ) AS temp_test
) as testing
SET t1.Name = testing.new_name where t1.id = testing.unique_id

最终输出如下所示:PICTURE


修改 出于性能考虑,这可能效果更好

1。首先运行此查询

SET SESSION group_concat_max_len = 1000000;  -- longer if needed
SET @query1 := (
SELECT 
    GROUP_CONCAT(DISTINCT unique_name) 
FROM temp
JOIN(
    select Name as unique_name
    FROM temp
    GROUP BY name
    HAVING COUNT(Name) > 1
) as t
);

2. 然后运行此更新

UPDATE temp t1, 
(
    SELECT 
        id as unique_id, 
        new_name 
    FROM(
        SELECT
          id,
          IF(@ROW = Name, @COUNT, @COUNT := 1),
          CONCAT(Name, ' - ', @COUNT) AS new_name,
          @ROW := Name,
          @COUNT := @COUNT + 1
        FROM temp
        JOIN (SELECT @COUNT := 0, @ROW := "") AS t
        WHERE FIND_IN_SET (`name`, @query1)
    ) AS temp_test
) as testing
SET t1.Name = testing.new_name where t1.id = testing.unique_id

我在我的本地测试了这个并且它可以运行,所以你应该能够运行它:)

答案 1 :(得分:0)

UPDATE    table_x AS upd
    SET   upd.Name = CONCAT(upd.Name, '-', upd.Id)
    WHERE upd.id IN(
                    SELECT    sel.id
                        FROM  table_x AS sel
                        WHERE sel.Name = upd.Name
                          AND sel.Id != upd.Id
                 );

答案 2 :(得分:0)

首先,您应该将重复的Id存储在临时表中。


Drop temporary table if not exist temp;

Create temporary table temp (
Select max(id)'id' from table_x group by Name having count(*)>1
);

Delete from table_x as x,temp as t where x.id = t.id;

重复执行此操作...在设置名称字段的唯一键后,U将获得唯一的行。