ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mysql – 给定行之间如何GROUP_CONCAT?

2019-08-07 02:17:43  阅读:235  来源: 互联网

标签:mysql mysql-5-5


我有一张桌子

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有