MySql 字符串函数GROUP_CONCAT实现将多条记录合并成一条


一、需求描述

多表联查,根据统计字体有多少标签,即将多条某个相同字段的其他字段合并。效果如下:

二、解决方案

1、初始方案

起初SQL如下:

SELECT t1.ProductName AS `名称`,t3.`Name` AS `标签` FROM fonttb t1
LEFT JOIN `fonttbtagmap` t2 ON t1.Id = t2.FontId
LEFT JOIN fonttbtag t3 ON t3.Id = t2.FontTagId

效果如下:

 很明显,这不是我要的效果。

2、最终方案

SELECT t1.ProductName AS `名称`,GROUP_CONCAT(DISTINCT t3.`Name` SEPARATOR ',' ) AS `标签` FROM    fonttb t1
LEFT JOIN `fonttbtagmap` t2 ON t1.Id = t2.FontId
LEFT JOIN fonttbtag t3 ON t3.Id = t2.FontTagId

效果如下:

这里使用了 GROUP_CONCAT完成了想要的效果。加DISTINCT 的目的是为了将标签排重。

三、 GROUP_CONCAT

官网介绍

1、语法结构

这个函数返回一个字符串结果,其中包含一个组中连接的非null值。 如果没有非NULL值,则返回NULL。 完整语法如下:  

GROUP_CONCAT([DISTINCT] expr [,expr ...]
             [ORDER BY {unsigned_integer | col_name | expr}
                 [ASC | DESC] [,col_name ...]]
             [SEPARATOR str_val])

示例:

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

在MySQL中,您可以获得表达式组合的连接值。

  • 要消除重复值,请使用DISTINCT子句。

  • 要对结果中的值进行排序,请使用ORDER BY子句。要反向排序,请在order by子句中将DESC(降序)关键字添加到要排序的列的名称。默认是升序;这可以使用ASC关键字显式指定。

  • 组中值之间的默认分隔符是逗号(,)。若要显式指定分隔符,请指定separator”。

  • 返回值是一个非二进制或二进制字符串,取决于参数是非二进制还是二进制字符串。结果类型为TEXT或BLOB,除非group_concat_max_len小于或等于512,在这种情况下,结果类型为VARCHAR或VARBINARY。如果在mysql客户端中调用GROUP_CONCAT(),二进制字符串结果将使用十六进制表示法显示,这取决于——binary-as-hex的值。

2、注意事项 

  • 结果被截断为group_concat_max_len系统变量给出的最大长度,该变量的默认值为1024。虽然返回值的最大有效长度受到max_allowed_packet值的限制,但是这个值可以设置得更高一些。在运行时更改group_concat_max_len的值的语法如下,其中val是一个无符号整数: 

SET [GLOBAL | SESSION] group_concat_max_len = val;

如:
SET GLOBAL group_concat_max_len = 1024;
SET SESSION group_concat_max_len = 1024;
  • 查看group_concat_max_len命令:
show variables like 'group_concat_max_len';