文章浏览 复制本页面地址

Mysql 分组查询 并筛选较大值的记录

总结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的时候已经达到了排序的结果。

标签:
上一篇:
下一篇: