mysql删除重复数据只保留一条

时间:2022-09-22 22:54:46

建表语句

CREATE TABLE `student` (
    `id` BIGINT (20),
    `s_name` VARCHAR (765),
    `age` INT (2)
); 
INSERT INTO `student` (`id`, `s_name`, `age`) VALUES('100','','15');
INSERT INTO `student` (`id`, `s_name`, `age`) VALUES('111','','14');
INSERT INTO `student` (`id`, `s_name`, `age`) VALUES('112','','12');
INSERT INTO `student` (`id`, `s_name`, `age`) VALUES('122','','10');
INSERT INTO `student` (`id`, `s_name`, `age`) VALUES('123','','13');
INSERT INTO `student` (`id`, `s_name`, `age`) VALUES('124','','11');
INSERT INTO `student` (`id`, `s_name`, `age`) VALUES('126','','11');

 在网上查到很多关于这道题的答案,但很多都是错的,比如

delete from student 
where s_name in (select s_name from student group by s_name having count(s_name) > 1) 
and id not in (select min(id) from people group by s_name having count(s_name)>1) 

这句话在MySQL里执行会报:

You can't specify target table 'student' for update in FROM clause

意思就是不能先select出同一表中的某些值,再update这个表(在同一语句中),即不能依据某字段值做判断再来更新某字段的值。

解决方案就是用通过中间表来规避这个错误,sql语句如下:

DELETE 
FROM
  student 
WHERE id NOT IN 
  (SELECT 
    a.id 
  FROM
    (SELECT 
      MIN(id) AS id 
    FROM
      student 
    GROUP BY s_name 
    HAVING COUNT(s_name) > 1) AS a) 

但是这样写会有个问题,会把s_name没有重复的数据也删掉例如:

INSERT INTO `student` (`id`, `s_name`, `age`) VALUES('122','张','10');这条数据

很多答案也没有考虑到这个问题,把s_name没有重复的数据排除掉就行了。

最后形成的语句如下:

 

DELETE 
FROM
  student 
WHERE id NOT IN 
  (SELECT 
    a.id 
  FROM
    (SELECT 
      MIN(id) AS id 
    FROM
      student 
    GROUP BY s_name 
    HAVING COUNT(s_name) > 1) AS a) 
  AND s_name IN 
  (SELECT 
    b.s_name 
  FROM
    (SELECT 
      s_name 
    FROM
      student 
    GROUP BY s_name 
    HAVING COUNT(s_name) > 1) AS b)