建表語句
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)