如何删除特定列上的重复项?

fkvaft9z  于 2021-07-24  发布在  Java
关注(0)|答案(4)|浏览(282)

我有一张这样的table:

// users
+----+----------+-------+---------------------+
| id |   name   |  age  | some other cols ..  |
+----+----------+-------+---------------------+
| 1  | Ali      | 15    | ..                  |
| 2  | John     | 15    | ..                  |
| 3  | Ali      | 22    | ..                  |
| 4  | Martin   | 18    | ..                  |
| 5  | Ali      | 15    | ..                  |
| 6  | John     | 30    | ..                  |
| 7  | John     | 15    | ..                  |
+----+----------+-------+---------------------+

我想在上添加一个复合唯一索引 name, age 柱。现在,它给了我 there are duplicates rows 错误。我已经在用了 INSERT IGNORE .. 但很遗憾 IGNORE mysql不再支持。
不管怎样,你知道如何删除两个行上值相同的行吗 name 以及 age 列并只保留其中一个(行之一)?换言之,我要删除上具有相同值的所有行 name 以及 age 除了其中一列。
因此,预期结果如下:

// users
+----+----------+-------+---------------------+
| id |   name   |  age  | some other cols ..  |
+----+----------+-------+---------------------+
| 1  | Ali      | 15    | ..                  |
| 2  | John     | 15    | ..                  |
| 3  | Ali      | 22    | ..                  |
| 4  | Martin   | 18    | ..                  |
| 6  | John     | 30    | ..                  |
+----+----------+-------+---------------------+

你知道我该怎么做吗?

gpfsuwkq

gpfsuwkq1#

我强烈建议将代码编写为:

delete u
    from users u join
         (select u2.name, u2.age, min(u2.id) as min_id
          from users u2
          group by u2.name, u2.age
          having count(*) > 1
         ) u2
         on u.name = u2.name and u.age = u2.age and u2.id > u.min_id;

使用 inner join> 他很聪明。但是,我认为它可能尝试多次更新同一行。
考虑这个例子:

id    name     age
 1    Doug      42
 2    Doug      42
 3    Doug      42
 4    Doug      42
 5    Doug      42

内部连接逻辑将尝试删除行“5”四次。此版本只删除一次。

muk1a3rh

muk1a3rh2#

希望这对你有用:

DELETE t1 
FROM users t1 
INNER JOIN users t2 
WHERE t1.id > t2.id AND t1.name = t2.name AND t1.age=t2.age;
9jyewag0

9jyewag03#

如果您只想以这种方式查看数据,那么基本选择可以实现以下功能:

SELECT t1.*
FROM yourTable t1
INNER JOIN
(
    SELECT name, age, MIN(id) AS min_id
    FROM yourTable
    GROUP BY name, age
) t2
    ON t2.name = t1.name AND t2.age = t1.age AND t2.min_id = t1.id
ORDER BY
    t1.id;

在关于具有相同名称和年龄值的两个或多个记录“重复”的情况下,上述查询任意地仅保留具有最小值的记录 id 其中的价值。

nhjlsmyf

nhjlsmyf4#

我为你的问题举了个例子:

CREATE TABLE #myList (
  id int,
  [name] VARCHAR(100),
  age  int
);
  --drop table #myList

INSERT INTO #myList
  (id, [name], age  )
VALUES
  (1,'Ali',15),
  (2,'John',15),
  (3,'Ali',22),
  (4,'Martin',18),
  (5,'Ali',15),
  (6,'John',30),
  (7,'John',15)

 select id,[name],age from  ( SELECT 
     i.id,
    i.[name] [name],
    i.age age,
    RANK() OVER (PARTITION BY i.[name] ORDER BY i.id DESC) AS Rank1,
        RANK() OVER (PARTITION BY i.age ORDER BY i.id DESC) AS Rank2
FROM #myList AS i 

) select1 where  select1.Rank1 =1 or select1.Rank2 =1

结果=

id  name    age
7   John    15
5   Ali     15
4   Martin  18
3   Ali     22
6   John    30

相关问题