联合中的MySQL group_concat(utf8)被截断为1024/3

时间:2017-12-09 22:33:11

标签: mysql group-concat

TLDR: group_concat(utf8 varchar) union itself仅返回group_concat_max_len/3个ASCII字符,就像字符长度是固定的而不是变量一样。 仅group_concat会按预期返回group_concat_max_len个字符。

问题

我有一个表tabletest,其中data列定义为UTF8 varchar(2048)。 表中只有一行,列中有1050个ASCII字符。

此表/列上的group_concat返回1024个字符(等于group_concat_max_len),这是预期的。

但是此group_concatgroup_concat相同的联合会返回341个字符(等于group_concat_max_len / 3)。

为什么会这样?

根据MySQL Aggregate (GROUP BY) Function Descriptions

  

除非group_concat_max_len小于或等于512,否则结果类型为TEXT或BLOB,在这种情况下,结果类型为VARCHAR或VARBINARY。

来自MySQL The BLOB and TEXT Types

  

同样,您可以将TEXT列视为VARCHAR列。 BLOB和TEXT在以下方面与VARBINARY和VARCHAR不同:

     
      
  • 对于BLOB和TEXT列的索引,必须指定索引前缀长度。对于CHAR和VARCHAR,前缀长度是可选的。请参见第8.3.4节“列索引”。
  •   
  • BLOB和TEXT列不能包含DEFAULT值。
  •   

因此返回类型应该是TEXT,它也是可变长度的,并且应该支持utf8中的ASCII字符为1字节宽。

确认问题的相关答案

MySQL Truncating of result when using Group_Concat and Concat

Weird result for GROUP_CONCAT on subquery

可能的罪魁祸首

再次来自MySQL The BLOB and TEXT Types

  

排序时只使用列的第一个max_sort_length个字节。 max_sort_length的默认值是1024

AFAIK UNION需要在删除重复项之前对行进行排序,因此这似乎是一个可能的原因。但是按set max_sort_length=2048;更改它会使更改返回的字符数。

唯一的解决方法似乎是SET group_concat_max_len = 1539;或更多。仅1538或更少只返回512或更少的字符。为什么这个奇怪的数字?

完整示例

create database uniontest collate utf8_general_ci;
create table uniontest.tabletest (data varchar(2048));
insert into uniontest.tabletest select repeat('a',1050);

简单选择1050个字符的长度:

select length(data) from uniontest.tabletest;

输出:

+--------------+
| length(data) |
+--------------+
|         1050 |
+--------------+

单行1050个字符的连续(因此不添加分隔符)。在服务器配置 group_concat_max_len = 1024

select length(group_concat(data separator ',')) from uniontest.tabletest;

输出按预期截断:

+------------------------------------------+
| length(group_concat(data separator ',')) |
+------------------------------------------+
|                                     1024 |
+------------------------------------------+

现在与自身结合(试图阻止其他数据类型转换):

select length(data) from (
select group_concat(data separator ',') as data from uniontest.tabletest union 
select group_concat(data separator ',') as data from uniontest.tabletest) d;

意外结果(期待1024):

+--------------+
| length(data) |
+--------------+
|          341 |
+--------------+

在MySQL 5.6和5.7上测试。

修改

发现有关ORDER BY而非UNION ORDER BY truncates GROUP_CONCAT result的错误报告。报告已关闭,可能只有ORDER BY案例已修复?

0 个答案:

没有答案