1. 程式人生 > >mysql查詢連續記錄

mysql查詢連續記錄

案例:

最近遇到一個業務需求, 需要查詢滿足條件且連續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:[email protected]+1) as b from cdb_labels a,(SELECT @b := 0) tmp_b where type=1;

這裡寫圖片描述

2、用自增的id減去自增列b:
select id,type,content,( id-(@b:[email protected]+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:[email protected]+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:[email protected]+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:[email protected]+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);

這裡寫圖片描述

總結建議:

  1. MySQL的函式例如: GROUP_CONCAT() 的字元長度有限制(預設1024),如果連續記錄較多會發生字元擷取報錯;
  2. 建議可以分步驟去查詢,防止巢狀子查詢,還可以提升效能而且避免使用MySQL函式;