我正在寻找一个能够从单个表中进行选择的查询,以便将属性相等的连续记录折叠在一起。与group by类似,但我不希望将属性的每个出现都分组在一起,而是希望为每个连续范围设置一个组。
示例表:

+-----+-----+
|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');

最佳答案

你能试试这个吗?你可以在这里测试。

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进行分组,即使它们具有相同的grp,也可以区分每个连续的组。
编辑:要在示例中获得准确的结果:
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

关于mysql - 选择具有公共(public)属性的连续记录组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21134737/

10-16 15:29