案例

最近遇到一个业务需求, 需要查找满足条件且连续3出现条以上的记录。

表结构:

create table `cdb_labels` (
  `id` int(10) unsigned not null auto_increment,
  `type` int(11) not null default '0' comment '标签类型:1喜欢异性类型,2擅长话题',
  `content` varchar(255) character set utf8 collate utf8_unicode_ci not null comment '标签内容',
  primary key (`id`)
) engine=innodb auto_increment=57 default charset=utf8 comment='标签内容';

所有数据:

select * from cdb_labels where type = 1;

解决思路

1.对满足初次查询的数据赋予一个自增列b

 select id,type,content,(@b:=@b+1) as b from cdb_labels a,(select @b := 0) tmp_b where type=1;

2.用自增的id减去自增列b

select id,type,content,( id-(@b:=@b+1) ) as c from cdb_labels a,(select @b := 0) tmp_b where type=1;

3.对等差列c分组, 并将分组的id组装起来

select count(id),group_concat(id) from ( 
    select id,( id-(@b:=@b+1) ) as c from cdb_labels a,(select @b := 0) tmp_b where type=1 
) as d group by c;

注:为了方便区分,这里查询分组成员要大于5(也就是连续出现超过5次的记录):

select if( count(id)>5 ,group_concat(id),null) e from ( 
    select id,( id-(@b:=@b+1) ) as c from cdb_labels a,(select @b := 0) tmp_b where type=1 
) as d group by c;

那么得到的数据只有:9,10,11,12,13,14,15 

4.根据组装的id去找数据

select id,type,content from cdb_labels,(
    select if( count(id)>5 ,group_concat(id),null) e from ( 
        select id,( id-(@b:=@b+1) ) as c from cdb_labels a,(select @b := 0) tmp_b where type=1 
    ) as d group by c
) as f where f.e is not null and find_in_set(id , f.e);

总结建议

  • mysql的函数例如: group_concat() 的字符长度有限制(默认1024),如果连续记录较多会发生字符截取报错;
  • 建议可以分步骤去查询,防止嵌套子查询,还可以提升性能而且避免使用mysql函数;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。