MySQL GROUP_CONCAT函数 将多行数据合并成一行

实际场景需求是这样的:

某网站的后台管理,新建一个用户时,需要指派给其一个角色,该角色具有一定权限:
比如,“销售专员”这个角色有A,B,C的权限,“销售经理”这个角色有A,B,C,E的权限,“财务”这个角色有B,C,D,E,F的权限。
(直接可以理解为ORACLE数据库中的“角色-权限”)

开发的同学需求是知道某个角色,获取其全部的权限,并在一条row中显示。

测试表建立:

  1. CREATE TABLE `a` (
  2.   `id` int(11) DEFAULT NULL,
  3.   `name` char(1) DEFAULT NULL
  4. ) ENGINE=InnoDB DEFAULT CHARSET=latin1
  1. INSERT INTO a SELECT 1,'A';
  2. INSERT INTO a SELECT 1,'B';
  3. INSERT INTO a SELECT 1,'C';
  4. INSERT INTO a SELECT 2,'A';
  5. INSERT INTO a SELECT 2,'B';
即:
  1. mysql> SELECT * FROM a;
  2. +------+------+
  3. | id   | name |
  4. +------+------+
  5. | 1    | A    |
  6. | 1    | B    |
  7. | 1    | C    |
  8. | 2    | A    |
  9. | 2    | B    |
  10. +------+------+
  11. 5 rows in set (0.00 sec)
要求显示为:

  1. +------+---------+
  2. | id   | name    |
  3. +------+---------+
  4. | 1    | C,A,A,B |
  5. | 2    | A,B     |
  6. +------+---------+

这里就需要用到GROUP_CONCAT函数
官方给出的简介是:
GROUP_CONCAT()
Return a concatenated string

给出的语法和例子是:

This function returns a string result with the concatenated non-NULL values from a group. It returns NULL if there are no non-NULL values. The full syntax is as follows:

GROUP_CONCAT([DISTINCT] expr [,expr ...]
             [ORDER BY {unsigned_integer | col_name | expr}
                 [ASC | DESC] [,col_name ...]]
             [SEPARATOR str_val])
mysql> SELECT student_name, 
    -> GROUP_CONCAT(test_score) 
    -> FROM student 
    -> GROUP BY student_name; 

Or:

mysql> SELECT student_name, 
    -> GROUP_CONCAT(DISTINCT test_score 
    -> ORDER BY test_score DESC SEPARATOR ' ') 
    -> FROM student 
    -> GROUP BY student_name;

简单来说,可以通过:

  1. mysql> SELECT id , GROUP_CONCAT(name) name
  2.     -> FROM
  3.     -> GROUP BY id;
来获得这样的结果集:

  1. +------+---------+
  2. | id   | name    |
  3. +------+---------+
  4. | 1    | A,A,B,C |
  5. | 2    | A,B     |
  6. +------+---------+

当然也可以对其的分隔符进行修改:
  1. mysql> SELECT idGROUP_CONCAT(name SEPARATOR ';')
  2.     -> FROM a
  3.     -> GROUP BY id;
这将使分隔符改为" ; "

同样也可以对name列进行排序:

  1. mysql> SELECT id, GROUP_CONCAT(name ORDER BY name DESC) name
  2.     -> FROM a
  3.     -> GROUP BY id;
  4. +------+---------+
  5. | id   | name    |
  6. +------+---------+
  7. | 1    | C,B,A,A |
  8. | 2    | B,A     |
  9. +------+---------+
  10. 2 rows in set (0.00 sec)

当然官方还给出了可以通过DISTINCT来排除冗余
用法如下:

  1. mysql> SELECT id, GROUP_CONCAT(DISTINCT name) name
  2.     -> FROM a
  3.     -> GROUP BY id;
  4. +------+-------+
  5. | id   | name  |
  6. +------+-------+
  7. | 1    | A,B,C |
  8. | 2    | A,B   |
  9. +------+-------+
  10. 2 rows in set (0.00 sec)




作者公众号(持续更新)




请使用浏览器的分享功能分享到微信等