数据库
首页 > 数据库> > mysql – 给定行之间如何GROUP_CONCAT?

mysql – 给定行之间如何GROUP_CONCAT?

作者:互联网

我有一张桌子

id  diary
1   breakfast
2   walk
3   start
4   office works
5   office projects
6   end
7   taxi
8   start
9   preparing for meeting
10  doing the meeting
11  end
12  night

我想在产品表的开始和结束之间进行CONCAT行:

id  type      diary
1             breakfast
2             walk
3   concated  office works, office projects
7             taxi
8   concated  preparing for meeting, doing the meeting
12            night

我想我需要在IF STATEMENT中使用GROUP_CONCAT,但不知道如何实现它.

解决方法:

这是您需要的查询:

set @groupnum = 0;
set @groupon = 0;
set @inc = 1;
select grpn,GROUP_CONCAT(diary ORDER BY id) itinerary_step from
(select
    @inc      := IF(@groupon=0,1,0)           inc,
    @groupnum := @groupnum + @inc             grpn,
    @s_tag    := IF(diary='start',1,0)        stag,
    @e_tag    := IF(diary='end',  1,0)        etag,
    @groupon  := IF(diary='start',1,@groupon) g1,
    @groupon  := IF(diary='end',  0,@groupon) g2,
    (@ordernum:=@e_tag*1000000+@s_tag)      ord,
    id,diary from diary
) A WHERE ord NOT IN (1,1000000) GROUP BY grpn;

首先,这是您的示例数据

mysql> use all_db
Database changed
mysql> drop table if exists diary;
Query OK, 0 rows affected (0.03 sec)

mysql> create table diary
    -> (
    ->     id int not null auto_increment,
    ->     diary varchar(25),
    ->     primary key (id)
    -> );
Query OK, 0 rows affected (0.11 sec)

mysql> insert into diary (diary) values ('breakfast'),('walk'),('start'),
    -> ('office works'),('office projects'),('end'),('taxi'),('start'),
    -> ('preparing for meeting'),('doing the meeting'),('end'),('night');
Query OK, 12 rows affected (0.06 sec)
Records: 12  Duplicates: 0  Warnings: 0

mysql> select * from diary;
+----+-----------------------+
| id | diary                 |
+----+-----------------------+
|  1 | breakfast             |
|  2 | walk                  |
|  3 | start                 |
|  4 | office works          |
|  5 | office projects       |
|  6 | end                   |
|  7 | taxi                  |
|  8 | start                 |
|  9 | preparing for meeting |
| 10 | doing the meeting     |
| 11 | end                   |
| 12 | night                 |
+----+-----------------------+
12 rows in set (0.00 sec)

mysql>

使用迭代变量操作

set @groupnum = 0;
set @groupon = 0;
set @inc = 1;
select * from
(select
    @inc      := IF(@groupon=0,1,0)           inc,
    @groupnum := @groupnum + @inc             grpn,
    @s_tag    := IF(diary='start',1,0)        stag,
    @e_tag    := IF(diary='end',  1,0)        etag,
    @groupon  := IF(diary='start',1,@groupon) g1,
    @groupon  := IF(diary='end',  0,@groupon) g2,
    (@ordernum:=@e_tag*1000000+@s_tag)      ord,
    id,diary from diary
) A;

这是它产生的:

mysql> set @groupnum = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> set @groupon = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> set @inc = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from
    -> (select
    ->     @inc      := IF(@groupon=0,1,0)           inc,
    ->     @groupnum := @groupnum + @inc             grpn,
    ->     @s_tag    := IF(diary='start',1,0)        stag,
    ->     @e_tag    := IF(diary='end',  1,0)        etag,
    ->     @groupon  := IF(diary='start',1,@groupon) g1,
    ->     @groupon  := IF(diary='end',  0,@groupon) g2,
    ->     (@ordernum:=@e_tag*1000000+@s_tag)      ord,
    ->     id,diary from diary
    -> ) A;
+-----+------+------+------+------+------+---------+----+-----------------------+
| inc | grpn | stag | etag | g1   | g2   | ord     | id | diary                 |
+-----+------+------+------+------+------+---------+----+-----------------------+
|   1 |    1 |    0 |    0 |    0 |    0 |       0 |  1 | breakfast             |
|   1 |    2 |    0 |    0 |    0 |    0 |       0 |  2 | walk                  |
|   1 |    3 |    1 |    0 |    1 |    1 |       1 |  3 | start                 |
|   0 |    3 |    0 |    0 |    1 |    1 |       0 |  4 | office works          |
|   0 |    3 |    0 |    0 |    1 |    1 |       0 |  5 | office projects       |
|   0 |    3 |    0 |    1 |    1 |    0 | 1000000 |  6 | end                   |
|   1 |    4 |    0 |    0 |    0 |    0 |       0 |  7 | taxi                  |
|   1 |    5 |    1 |    0 |    1 |    1 |       1 |  8 | start                 |
|   0 |    5 |    0 |    0 |    1 |    1 |       0 |  9 | preparing for meeting |
|   0 |    5 |    0 |    0 |    1 |    1 |       0 | 10 | doing the meeting     |
|   0 |    5 |    0 |    1 |    1 |    0 | 1000000 | 11 | end                   |
|   1 |    6 |    0 |    0 |    0 |    0 |       0 | 12 | night                 |
+-----+------+------+------+------+------+---------+----+-----------------------+
12 rows in set (0.00 sec)

mysql>

经过一些改进

>忽略ord = 1和ord = 1000000
>在grpn上的GROUP BY

这是最先提到的最终查询

set @groupnum = 0;
set @groupon = 0;
set @inc = 1;
select grpn,GROUP_CONCAT(diary ORDER BY id) itinerary_step from
(select
    @inc      := IF(@groupon=0,1,0)           inc,
    @groupnum := @groupnum + @inc             grpn,
    @s_tag    := IF(diary='start',1,0)        stag,
    @e_tag    := IF(diary='end',  1,0)        etag,
    @groupon  := IF(diary='start',1,@groupon) g1,
    @groupon  := IF(diary='end',  0,@groupon) g2,
    (@ordernum:=@e_tag*1000000+@s_tag)      ord,
    id,diary from diary
) A WHERE ord NOT IN (1,1000000) GROUP BY grpn;

这里执行:

mysql> set @groupnum = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> set @groupon = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> set @inc = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> select grpn,GROUP_CONCAT(diary ORDER BY id) itinerary_step from
    -> (select
    ->     @inc      := IF(@groupon=0,1,0)           inc,
    ->     @groupnum := @groupnum + @inc             grpn,
    ->     @s_tag    := IF(diary='start',1,0)        stag,
    ->     @e_tag    := IF(diary='end',  1,0)        etag,
    ->     @groupon  := IF(diary='start',1,@groupon) g1,
    ->     @groupon  := IF(diary='end',  0,@groupon) g2,
    ->     (@ordernum:=@e_tag*1000000+@s_tag)      ord,
    ->     id,diary from diary
    -> ) A WHERE ord NOT IN (1,1000000) GROUP BY grpn;
+------+-----------------------------------------+
| grpn | itinerary_step                          |
+------+-----------------------------------------+
|    1 | breakfast                               |
|    2 | walk                                    |
|    3 | office works,office projects            |
|    4 | taxi                                    |
|    5 | preparing for meeting,doing the meeting |
|    6 | night                                   |
+------+-----------------------------------------+
6 rows in set (0.00 sec)

mysql>

试试看 !!!

警告

我针对我的样本数据尝试了@a1ex07’s query

mysql> select d.id1,
    -> CASE
    -> WHEN COUNT(*) >1 THEN 'concatenated'
    -> ELSE NULL
    -> END AS `type`,
    -> GROUP_CONCAT(
    -> case
    -> when diary = 'start' or diary = 'end' then null
    -> else diary
    -> end
    -> order by id
    -> ) as diary
    -> FROM
    -> (
    -> SELECT x.id, x.diary,
    -> CASE WHEN start_id IS NULL OR end_id IS NULL OR start_id > end_id THEN id
    -> ELSE start_id
    -> END as id1,
    -> end_id
    -> FROM
    -> (
    ->     select a.*,
    ->     (select max(id) from diary b where b.diary ='start' and b.id <=a.id) as start_id,
    ->     (select min(id) from diary b where b.diary ='end' and b.id >=a.id) as end_id
    ->
    ->      from diary a
    ->  )x
    -> )d
    -> group by id1,end_id;
+------+--------------+-----------------------------------------+
| id1  | type         | diary                                   |
+------+--------------+-----------------------------------------+
|    1 | NULL         | breakfast                               |
|    2 | NULL         | walk                                    |
|    3 | concatenated | office works,office projects            |
|    3 | NULL         | taxi                                    |
|    8 | concatenated | preparing for meeting,doing the meeting |
|   12 | NULL         | night                                   |
+------+--------------+-----------------------------------------+
6 rows in set (0.00 sec)

mysql>

乔治,它的作品!他先得到答案,得到1分.

标签:mysql,mysql-5-5
来源: https://codeday.me/bug/20190807/1605570.html