总结mysql查找重复行且按一定条件保留所重复的数据中的一条记录:
第一种情况,判断保留记录的条件是主键或是唯一值
--
-- 表的结构 `test`
--
CREATE TABLE IF NOT EXISTS `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(16) NOT NULL,
`phone` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- 导出表中的数据 `test`
--
INSERT INTO `test` (`id`, `name`, `phone`) VALUES
(1, 'a', 1234),
(2, 'a', 3333),
(3, 'b', 555),
(4, 'b', 6773),
(5, 'a', 743),
(6, 'c', 95434);
查询一下,
SELECT * FROM `test` group by name
得到
id name phone
1 a 1234
3 b 555
6 c 95434
但我们想得到id最大的name怎么办?
SELECT max(id),id,name,phone FROM test group by name
得到
max(id) id name phone
5 1 a 1234
4 3 b 555
6 6 c 95434
可以看到,虽然每个name的最大id得到了,但是,其他数据依然是每个name的第一行,此处需要注意
用子查询
select * from (select * from test order by id desc) t group by name
id name phone
5 a 743
4 b 6773
6 c 95434
这就是我们想要的结果了,记录看起来在执行group的时候,会按name进行排序(有待确定group和order的关系)。但是,这种作法在行数非常多的情况下,相当于把整个表复制了一次,效率比较低,在对31144条数据进行测试的时候,用时58.437s
那用这种子查询 select * from test t where id in (select max(id) from test group by name)
得到
id name phone
4 b 6773
5 a 743
6 c 95434
然而,这种子查询因为用了in,在对31144条数据进行测试的时候,效率更低,用时达15万s,所以当数据量大时,最好不要用此查询。
第二种情况,判断保留记录的条件是重复值
--
-- 表的结构 `message`
--
CREATE TABLE `message` (
`pid` int(11) NOT NULL,
`nums` int(11) default NULL,
`source_type` char(255) default NULL,
`source_id` int(11) default NULL,
`source_name` char(255) default NULL,
`columnId` int(11) default NULL,
`category` char(255) default NULL,
`cp_id` char(255) default NULL,
` company` char(255) default NULL,
`online` char(255) default NULL,
`last_modify_time` char(255) default NULL,
`operator_system` char(255) default NULL,
`java_platform` char(255) default NULL,
`screen_length` int(11) default NULL,
`screen_width` int(11) default NULL,
PRIMARY KEY (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
数据按以下9个字段判定重复,且按字段的先后顺序进行分组和排序:
online,source_type,
columnId,source_name,category,operator_system,java_platform,screen_length,screen_width
以上条件重复的记录按字段last_modify_time判定,保留时间最早的记录,删除其他重复的数据
select * from (select * from message21 order by last_modify_time ) t group by online,source_type,
columnId,source_name,category,operator_system,java_platform,screen_length,screen_width
同样,对于排序,实际上group的时候已经达到了排序的结果。