一、需求描述
多表联查,根据统计字体有多少标签,即将多条某个相同字段的其他字段合并。效果如下:
二、解决方案
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';