`

mysql中好用的函数group_concat

阅读更多
在mysql中,有个不错的函数group_concat,主要作用是用来应付如一对多情况的变体的

完整的语法如下:

group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])

比如建立一个模拟的表;
CREATE TABLE `group_c` (
`parent_id` int(11) DEFAULT NULL,
`child_id` int(11) DEFAULT NULL
) ENGINE=InnoDB;
INSERT INTO group_c(parent_id, child_id)
VALUES (1,1),(1,2),(1,3),(2,1),(2,4),(1,4),(2,6),(3,1),(3,2),(4,1),(4,1),(1,1),(5,0);

查询一下:
SELECT DISTINCT
    -> parent_id, child_id
    -> FROM group_c
    -> ORDER BY parent_id;
+-----------+----------+
| parent_id | child_id |
+-----------+----------+
|         1 |        1 |
|         1 |        2 |
|         1 |        3 |
|         1 |        4 |
|         2 |        1 |
|         2 |        3 |
|         2 |        4 |
|         2 |        6 |
|         3 |        1 |
|         3 |        2 |
|         4 |        1 |
|         5 |        0 |
+-----------+----------+
12 rows in set (0.00 sec)

   可以看到,parent_id和child_id是一对多的情况
  而如果使用group_concat函数,则
SELECT DISTINCT
    -> parent_id, GROUP_CONCAT(DISTINCT child_id ORDER BY child_id) AS child_id_list
    -> FROM group_c
    -> group by parent_id
    -> ORDER BY parent_id;
+-----------+---------------+
| parent_id | child_id_list |
+-----------+---------------+
|         1 | 1,2,3,4       |
|         2 | 1,3,4,6       |
|         3 | 1,2           |
|         4 | 1             |
|         5 | 0             |
+-----------+---------------+
5 rows in set (0.00 sec)

  可以看到,其具体区别了,默认是用逗号分隔的;

还可以在group_concat中做文章,比如:
select id,group_concat(distinct name) from aa group by id; 
  这里是在group_concat(distinct name)列中,去掉重复的name;

select id,group_concat(name order by name desc) from aa group by id; 

又比如;
mysql> SELECT DISTINCT
    -> parent_id, GROUP_CONCAT(DISTINCT child_id ORDER BY child_id) AS child_id_list
    -> FROM group_c
    -> group by parent_id
    -> ORDER BY parent_id;
+-----------+---------------+
| parent_id | child_id_list |
+-----------+---------------+
|         1 | 1,2,3,4       |
|         2 | 1,3,4,6       |
|         3 | 1,2           |
|         4 | 1             |
|         5 | 0             |
+-----------+---------------+
5 rows in set (0.00 sec)

来点复杂的例子,比如
engineers (id, name, surname, URL) – 工程师
customers (id, company name, URL) –客户
issues (id, customer_id, description) – 每个客户咨询的问题
workflow (id, engineer_id, issue_id) – 每个工程师要回答的问题




-- Engineers
CREATE TABLE engineers (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
e_name VARCHAR(30) NOT NULL,
e_surname VARCHAR(30) NOT NULL,
url VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;
-- Customers
CREATE TABLE customers (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
company_name VARCHAR(30) NOT NULL,
url VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;
-- Issues (Issue-Customer)
CREATE TABLE issues (
id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
customer_id VARCHAR(30) NOT NULL,
description TEXT,
PRIMARY KEY (id)
) ENGINE=InnoDB;
-- Workflow (Action: Engineer-Issue(Customer))
CREATE TABLE workflow (
action_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
engineer_id SMALLINT UNSIGNED NOT NULL,
issue_id SMALLINT UNSIGNED NOT NULL,
PRIMARY KEY (action_id)
) ENGINE=InnoDB;
INSERT INTO engineers (e_name, e_surname, url)
VALUES
('Miguel', 'Nieto', 'http://www.percona.com/about-us/our-team/miguel-angel-nieto'),
('Marcos', 'Albe', 'http://www.percona.com/about-us/our-team/marcos-albe'),
('Valerii', 'Kravchuk', 'http://www.percona.com/about-us/our-team/valerii-kravchuk'),
('Michael', 'Rikmas', 'http://www.percona.com/about-us/our-team/michael-rikmas');
INSERT INTO customers (company_name, url)
VALUES
('OT','http://www.ovaistariq.net/'),
('PZ','http://www.peterzaitsev.com/'),
('VK','http://mysqlentomologist.blogspot.com/'),
('FD','http://www.lefred.be/'),
('AS','http://mysqlunlimited.blogspot.com/'),
('SS','https://www.flamingspork.com/blog/');
INSERT INTO issues(customer_id, description)
VALUES
(1,'Fix replication'),
(2,'Help with installation of Percona Cluster'),
(3,'Hardware suggestions'),
(4,'Error: no space left'),
(5,'Help with setup daily backup by Xtrabackup'),
(6,'Poke sales about Support agreement renewal'),
(4,'Add more accounts for customer'),
(2,'Create Hot Fix of Bug 1040735'),
(1,'Query optimisation'),
(1,'Prepare custom build for Solaris'),
(2,'explain about Percona Monitoring plugins'),
(6,'Prepare access for customer servers for future work'),
(5,'Decribe load balancing for pt-online-schema-change'),
(4,'Managing deadlocks'),
(1,'Suggestions about buffer pool size');
INSERT INTO workflow (engineer_id, issue_id)
VALUES (1,1),(4,2),(2,3),(1,4),(3,5),(2,6),(3,7),(2,8),(2,9),(1,10),(3,11),(2,12),(2,13),(3,14),(1,15),(1,9),(4,14),(2,9),(1,15),(3,10),(4,2),(2,15),(4,8),(4,4),(3,11),(1,7),(3,7),(1,1),(1,9),(3,4),(4,3),(1,5),(1,7),(1,4),(2,4),(2,5);



则:
列出每个工程师要回答的问题:
SELECT
    ->  CONCAT (e_name, ' ', e_surname) AS engineer,
    ->  GROUP_CONCAT(DISTINCT issue_id, ' (', c.company_name,')' ORDER BY issue_id SEPARATOR ', ' ) AS 'issue (customer)'
    -> FROM
    ->  workflow w,
    ->  engineers e,
    ->  customers c,
    ->  issues i
    -> WHERE
    ->  w.engineer_id = e.id
    ->  AND w.issue_id = i.id
    ->  AND i.customer_id = c.id
    -> GROUP BY
    ->  e.id
    -> ORDER BY
    ->  e_name, e_surname;
+------------------+---------------------------------------------------------------------------+
| engineer         | issue (customer)                                                          |
+------------------+---------------------------------------------------------------------------+
| Marcos Albe      | 3 (VK), 4 (FD), 5 (AS), 6 (SS), 8 (PZ), 9 (OT), 12 (SS), 13 (AS), 15 (OT) |
| Michael Rikmas   | 2 (PZ), 3 (VK), 4 (FD), 8 (PZ), 14 (FD)                                   |
| Miguel Nieto     | 1 (OT), 4 (FD), 5 (AS), 7 (FD), 9 (OT), 10 (OT), 15 (OT)                  |
| Valerii Kravchuk | 4 (FD), 5 (AS), 7 (FD), 10 (OT), 11 (PZ), 14 (FD)                         |
+------------------+---------------------------------------------------------------------------+
4 rows in set (0.00 sec)

列出每个客户对应的问题,以及这些问题由什么工程师面对:

SELECT
    ->  c.company_name AS company,
    ->  GROUP_CONCAT(DISTINCT issue_id, ' (', engineer_list, ')' ORDER BY issue_id SEPARATOR ', ' ) AS issue
    -> FROM
    ->  workflow w,
    ->  engineers e,
    ->  customers c,
    ->  issues i,
    ->  (SELECT
    ->    i.id AS i_id,
    ->    GROUP_CONCAT(DISTINCT CONCAT(e_name, ' ', e_surname) ORDER BY e_name SEPARATOR ', ') AS engineer_list
    ->   FROM
    ->    workflow w,
    ->    engineers e,
    ->    issues i
    ->   WHERE
    ->    w.engineer_id = e.id
    ->    AND w.issue_id = i.id
    ->   GROUP BY
    ->    i.id) AS e_list
    -> WHERE
    ->  w.engineer_id = e.id
    ->  AND w.issue_id = i.id
    ->  AND i.customer_id = c.id
    ->  AND w.issue_id = e_list.i_id
    -> GROUP BY
    ->  c.id
    -> ORDER BY
    ->  c.company_name;
+---------+--------------------------------------------------------------------------------------------------------------------------------------------+
| company | issue (engineer)                                                                                                                           |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------+
| AS      | 5 (Marcos Albe, Miguel Nieto, Valerii Kravchuk), 13 (Marcos Albe)                                                                          |
| FD      | 4 (Marcos Albe, Michael Rikmas, Miguel Nieto, Valerii Kravchuk), 7 (Miguel Nieto, Valerii Kravchuk), 14 (Michael Rikmas, Valerii Kravchuk) |
| OT      | 1 (Miguel Nieto), 9 (Marcos Albe, Miguel Nieto), 10 (Miguel Nieto, Valerii Kravchuk), 15 (Marcos Albe, Miguel Nieto)                       |
| PZ      | 2 (Michael Rikmas), 8 (Marcos Albe, Michael Rikmas), 11 (Valerii Kravchuk)                                                                 |
| SS      | 6 (Marcos Albe), 12 (Marcos Albe)                                                                                                          |
| VK      | 3 (Marcos Albe, Michael Rikmas)                                                                                                            |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------+
6 rows in set (0.00 sec)
3
0
分享到:
评论

相关推荐

    【GROUP_CONCAT】使用之MySQL官方文档翻译

    `GROUP_CONCAT` 结果的长度受到 `group_concat_max_len` 系统变量的限制,默认值为 1024 字节。如果结果超过了这个长度,将会被截断。可以通过以下语句动态调整这个值: ```sql SET SESSION group_concat_max_...

    MySQL统计函数GROUP_CONCAT使用陷阱分析

    MySQL中的GROUP_CONCAT函数是一个非常实用的统计函数,它允许我们合并特定列的值,并以指定的分隔符连接它们。然而,在某些情况下,如果不注意,可能会遇到一些使用陷阱,导致数据被截断或者出现警告。本文将深入...

    MySQL GROUP_CONCAT限制解决方案

    作用:  GROUP_CONCAT函数可以拼接某个字段值成字符串,默认的分隔符是 逗号,即...SHOW VARIABLES LIKE 'group_concat_max_len' 操作方法:(如图) 调整长度设置方法: (1)在MySQL配置文件中加入:  文件:my.ini

    如何修改Mysql中group_concat的长度限制

    在MySQL数据库中,`GROUP_CONCAT` 函数是一个非常实用的工具,它允许你在聚合查询中将多个行的某个列值合并成一个单一的字符串,每个值之间由默认的逗号分隔。然而,当你处理大量数据时,可能会遇到一个限制,即`...

    MySQL中group_concat函数深入理解

    MySQL中的`GROUP_CONCAT`函数是一个非常实用的聚合函数,它允许你在分组查询中将一组行的某个列值合并成一个字符串,每个值之间由指定的分隔符隔开。这个函数对于数据汇总和报告生成特别有用,因为它可以把多行数据...

    mysql中GROUP_CONCAT的使用方法实例分析

    在MySQL中,`GROUP_CONCAT` 是一个非常实用的聚合函数,它允许你在分组查询时将同一组内的多个值合并成一个字符串。这个函数在处理列表或者集合数据时非常有用,尤其在需要将关联表中的多行数据整合成一行展示时。...

    MySQL拼接字符串函数GROUP_CONCAT详解

    MySQL中的GROUP_CONCAT函数是一个非常实用的聚合函数,主要用于在分组查询中将同一组内的多个值合并为一个字符串,通常用于数据汇总和报告。它能够处理非NULL值,并且可以进行排序、去重和自定义分隔符,极大地提高...

    Mysql的GROUP_CONCAT()函数使用方法

    MySQL中的GROUP_CONCAT()函数是一个非常实用的聚合函数,它允许你在分组查询时将同一组内的多个值合并成一个字符串。此函数主要用于数据分析和报表生成,尤其在处理多对多关系的数据时,能简化数据处理流程。在本文...

    解决Oracle没有WM_CONCAT函数.zip

    在Oracle数据库中,WM_CONCAT是一个非常实用的聚合函数,用于将一组字符串连接成一个单一的字符串,类似于SQL Server中的STRING_AGG或MySQL中的GROUP_CONCAT。然而,Oracle官方并没有提供这个函数,它是一个第三方...

    mysql group_concat()函数用法总结

    MySQL中的`GROUP_CONCAT()`函数是一个非常实用的聚合函数,用于在分组查询中将同一组内多个记录的某个字段值合并成一个字符串,各值之间由用户指定的分隔符(默认为逗号)隔开。这个函数在处理报表和数据分析时特别...

    mysql的group_concat函数使用示例

    MySQL中的`GROUP_CONCAT`函数是一个非常实用的聚合函数,用于在分组查询时将同一组内多个相同字段的值合并成一个字符串,各值之间用指定的分隔符隔开。这个函数对于数据报告、汇总和数据分析非常有用。下面我们将...

    GROUP_CONCAT的用法

    2. GROUP_CONCAT 函数的结果集最大长度为 1024 字符,可以使用 `GROUP_CONCAT_MAX_LEN` 系统变量来调整结果集的最大长度。 3. GROUP_CONCAT 函数忽略空值,可以使用 `COALESCE` 函数来处理空值。 GROUP_CONCAT 函数...

    浅谈MySQL中group_concat()函数的排序方法

    在MySQL数据库中,`GROUP_CONCAT()` 是一个非常实用的聚合函数,它允许我们将相同分组内的多个值合并成一个字符串,用特定的分隔符隔开。在处理需要汇总和展示多列数据时,这个函数尤其有用。本文将深入探讨 `GROUP_...

    Mysql5.7中使用group concat函数数据被截断的问题完美解决方法

    总结来说,当在MySQL 5.7中遇到`GROUP_CONCAT`函数数据被截断的问题时,关键在于调整`group_concat_max_len`变量的值。根据需求,可以选择修改配置文件或通过SQL命令临时调整该值。正确设置后,可以确保`GROUP_...

    SqlServer GroupConcat

    在SQL Server中,`GroupConcat`函数是一种非常实用的功能,特别是在处理聚合数据并希望返回一组字符串,而不是单个值时。然而,与MySQL等其他数据库系统不同,SQL Server原生并不支持`GroupConcat`。因此,为了在SQL...

Global site tag (gtag.js) - Google Analytics