mysql刪除重復數據只保留一條


建表語句

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)

  

或者是

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM