MySQL

准备数据

  1. CREATE TABLE `animal` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `name` varchar(20) DEFAULT NULL,
  4. `age` int(11) DEFAULT NULL,
  5. PRIMARY KEY (`id`)
  6. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
  7. INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('1', 'cat', '12');
  8. INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('2', 'dog', '13');
  9. INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('3', 'camel', '25');
  10. INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('4', 'cat', '32');
  11. INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('5', 'dog', '42');

目标:要去掉name相同的数据。
先看看哪些数据重复了

  1. SELECT name,count( 1 )
  2. FROM
  3. student
  4. GROUP BY
  5. NAME
  6. HAVING
  7. count( 1 ) > 1;

输出:

  1. name count(1) cat 2 dog 2

name为cat和dog的数据重复了,每个重复的数据有两条;

  1. Select * From Where 重复字段 In (Select 重复字段 From Group By 重复字段 Having Count(1)>1)

删除全部重复数据,一条不留

直接删除会报错

  1. DELETE
  2. FROM
  3. student
  4. WHERE
  5. NAME IN (
  6. SELECT NAME
  7. FROM
  8. student
  9. GROUP BY
  10. NAME
  11. HAVING
  12. count( 1 ) > 1)

报错:

  1. 1093 - You can't specify target table 'student' for update in FROM clause, Time: 0.016000s

原因是:更新这个表的同时又查询了这个表,查询这个表的同时又去更新了这个表,可以理解为死锁。mysql不支持这种更新查询同一张表的操作
解决办法:把要更新的几列数据查询出来做为一个第三方表,然后筛选更新。

  1. DELETE
  2. FROM
  3. student
  4. WHERE
  5. NAME IN (
  6. SELECT
  7. t.NAME
  8. FROM
  9. ( SELECT NAME FROM student GROUP BY NAME HAVING count( 1 ) > 1 ) t)

删除表中删除重复数据,仅保留一条

在删除之前,可以先查一下,要删除的重复数据是啥样的

  1. SELECT
  2. *
  3. FROM
  4. student
  5. WHERE
  6. id NOT IN (
  7. SELECT
  8. t.id
  9. FROM
  10. ( SELECT MIN( id ) AS id FROM student GROUP BY `name` ) t )

先通过name分组,查出id最小的数据,这些数据就是要留下的火种,那么再查询出id不在这里面的,就是要删除的重复数据。

开始删除重复数据,仅留一条

刚才的select换成delete即可

  1. DELETE
  2. FROM
  3. student
  4. WHERE
  5. id NOT IN (
  6. SELECT
  7. t.id
  8. FROM
  9. ( SELECT MIN( id ) AS id FROM student GROUP BY `name` ) t )