繁体   English   中英

选择具有公共属性的连续记录组?

[英]Selecting groups of consecutive records with a common attribute?

我正在寻找能够从单个表中进行选择的查询,使得属性相等的连续记录被折叠在一起。 类似于分组,但不是将属性的每个出现分组在一起,我想为每个连续范围分组。

示例表:

+-----+-----+
|order|group|
+-----+-----+
|1    |aaa  |
+-----+-----+
|2    |aaa  |
+-----+-----+
|3    |bbb  |
+-----+-----+
|4    |aaa  |
+-----+-----+
|5    |aaa  |
+-----+-----+
|6    |aaa  |
+-----+-----+
|7    |ccc  |
+-----+-----+
|8    |aaa  |
+-----+-----+

示例所需结果:

+-----+-------------------+
|group|group_concat(order)|
+-----+-------------------+
|aaa  |1,2                |
+-----+-------------------+
|bbb  |3                  |
+-----+-------------------+
|aaa  |4,5,6              |
+-----+-------------------+
|ccc  |7                  |
+-----+-------------------+
|aaa  |8                  |
+-----+-------------------+

我不能使用存储过程。

我有一个模糊的概念,我需要至少一个级别的嵌套来排序表(可能更多),并且可能必须使用变量,但不多于此。 如果您需要更多详细信息,请与我们联系。

编辑:查询创建示例:

create temporary table tab (
    ord int,
    grp varchar(8)
);

insert into tab (ord, grp) values
(1, 'aaa'),
(2, 'aaa'),
(3, 'bbb'),
(4, 'aaa'),
(5, 'aaa'),
(6, 'aaa'),
(7, 'ccc'),
(8, 'aaa');

你能试试吗? 你可以在这里测试http://www.sqlfiddle.com/#!2/57967/12

Select grp_new, group_concat(ord)
From (
   Select ord, if(grp = @prev, @seq, @seq := @seq + 1) as seq,
    if(grp = @prev, grp, @prev := grp) as grp_new
  From tab, (SELECT @seq := 0, @prev := '') AS init
  Order by ord
) x
Group by grp_new, seq;

关键思想是为相同的连续组生成相同的seq ,如下所示。

Select
   ord, if(grp = @prev, @seq, @seq := @seq + 1) as seq,
    if(grp = @prev, grp, @prev := grp) as grp_new
From tab, (SELECT @seq := 0, @prev := '') AS init
Order by ord

然后最后将GROUP BY grp, seq分组GROUP BY grp, seq即使它们具有相同的grp GROUP BY grp, seq也可以区分每个连续的组。

编辑:要获得示例中的结果:

Select grp_new, group_concat(ord order by ord)
From (
  Select ord, if(grp = @prev, @seq, @seq := @seq + 1) as seq,
    if(grp = @prev, grp, @prev := grp) as grp_new
  From tab, (SELECT @seq := 0, @prev := '') AS init
  Order by ord
) x
Group by seq

采用:

    select pquery.group, GROUP_CONCAT(pquery.order separator ', ') as order FROM
(  select t.*, @lastSeq := if( t.group != @lastGroup                                 
                      , 0, @lastSeq + 1 )
               as groupSeq,
     @lastGroup := t.group,
     @cont := if(@lastSeq =0, @cont + 1, @cont) as counter,
     @cgroup := concat(@cont,t.group) as cgroup
   from t, ( select @lastGroup := '',
   @lastSeq := 0, @cont :=0) sqlVars
 ) pquery 
group by pquery.cgroup

使用变量group_concat_max_len = 1024(结果限制,以字节为单位)为carfeul。 根据您的需求进行更改。

我将创建一个包含上面所有列的临时表,并添加2列id int(自动增量用于循环)groupid int并将上面的结果插入其中,然后使用int值更新新的groupid列,这将创建您需要看到的分组下面..

使用while循环填充临时表后,循环临时表中的记录。 临时表需要增加的id列,没有间隙,即1,2,3,4,5,6,7,8 ....无论您的结果如何。

在循环内部检查此行的组=最后一行组是否将groupid设置为groupid,否则设置为groupid + 1。 并将groupid重置为groupid = groupid + 1。

所以对于你的eaxample,groupid以0开头,然后读取第一行并将groupid设置为groupid(0)。 然后读取第2行检查group = last rows groupd>是的确如此row> group id = groupid。

读取行3组匹配最后一行组>否> groupid = groupid + 1然后将groupid设置为groupid。

检查4,5,6,7等

完成所有操作后,只需按新列分组即可获得所需的结果。 希望这可以帮助。 没有循环,我无法看到另一种方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM