[英]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.