MySQL 和 GROUP_CONCAT() 最大长度

Posted

技术标签:

【中文标题】MySQL 和 GROUP_CONCAT() 最大长度【英文标题】:MySQL and GROUP_CONCAT() maximum length 【发布时间】:2011-02-03 18:01:48 【问题描述】:

我在 mysql 查询中使用GROUP_CONCAT() 将多行转换为单个字符串。 但是,此函数的结果最大长度为1024 个字符。

我很清楚我可以更改参数group_concat_max_len 以增加此限制:

SET SESSION group_concat_max_len = 1000000;

但是,在我使用的服务器上,我无法更改任何参数。不是通过使用前面的查询,也不是通过编辑任何配置文件。

所以我的问题是: 有没有其他方法可以将多行查询的输出转换为单个字符串?

【问题讨论】:

你的意思是除了做客户端的工作吗? 谢谢哥们...你的问题是我的问题的答案:) 您似乎已经选择了一个答案,但出于好奇,您为什么不能使用SET 语句来更改会话变量? 那是因为我必须创建的查询嵌入在一些腐烂的自制 php 框架中,并且不允许我编辑任何其他部分。这个项目的编码方式真的很可耻。 我想知道当使用 group_concat 函数时,我的字符串返回中断,我不知道这个函数返回有限数量的字符,谢谢哥们,你的问题让我明白了 :) 【参考方案1】:
SET SESSION group_concat_max_len = 1000000;

是一个临时的、会话范围的设置。它仅适用于当前会话您应该像这样使用它。

SET SESSION group_concat_max_len = 1000000;
select group_concat(column) from table group by column

您甚至可以在共享主机中执行此操作,但是当您使用其他会话时,您需要重复 SET SESSION 命令。

【讨论】:

我更喜欢使用 GLOBAL 而不是 SESSION: SET GLOBAL group_concat_max_len=6999 以使设置在查询中有效 Rackspace 和其他云服务器不允许 GLOBAL 访问。我尝试使用 jdbc.execute("SET SESSION group_concat_max_len = ...");在道初始化方法中,但正如 keatkeat 所说,这只是暂时的。如果有人知道永久进行此更改的正确方法,请告诉我【参考方案2】:

设置最大长度的正确参数是:

SET @@group_concat_max_len = value_numeric;

value_numeric 必须 > 1024;默认情况下,group_concat_max_len 的值为 1024。

【讨论】:

SET SESSION 和 SET GLOBAL 在某个服务器上不起作用,但它确实起作用了!谢谢! 这有效,而其他建议没有 @ MySQL Server 5.1.41(我知道它是旧版本) 您实际上可以将group_concat_max_len 设置为低至4。 (mysql docs)。 “value_numeric 必须 >= 4”就是这种情况。我实际上用它来测试当你超过group_concat_max_len 值时会发生什么。 我可以确认这个参数是绝对的NOTreboot-proof:一旦mysql重新启动,属性被重置为1024,所以对我来说是-1 @NoWay 您必须在配置文件(例如 my.cnf)中设置该值,以便在重新启动 mysql 时应用该设置。没有SET查询会在重启后影响设置。【参考方案3】:

在 xampp my.ini 配置文件中包含此设置:

[mysqld]
group_concat_max_len = 1000000

然后重启xampp mysql

【讨论】:

【参考方案4】:

你可以试试这个

SET GLOBAL group_concat_max_len = 1000000;

【讨论】:

我正在为我的数据库运行这是 sqlyog 客户端,但它没有反映。但是当我通过我的 java 程序运行它时它似乎可以工作【参考方案5】:

正确的语法是mysql> SET @@global.group_concat_max_len = integer; 如果您没有权限在数据库所在的服务器上执行此操作,请使用如下查询: mySQL="SET @@session.group_concat_max_len = 10000;"或其他值。下一行:SET objRS = objConn.Execute(mySQL) 您的变量可能不同。 那么mySQL="SELECT GROUP_CONCAT(......);"等 我使用最后一个版本,因为我没有权限全局更改默认值 1024(使用 cPanel)。 希望这会有所帮助。

【讨论】:

【参考方案6】:
CREATE TABLE some_table (
  field1 int(11) NOT NULL AUTO_INCREMENT,
  field2 varchar(10) NOT NULL,
  field3 varchar(10) NOT NULL,
  PRIMARY KEY (`field1`)
);

INSERT INTO `some_table` (field1, field2, field3) VALUES
(1, 'text one', 'foo'),
(2, 'text two', 'bar'),
(3, 'text three', 'data'),
(4, 'text four', 'magic');

这个查询有点奇怪,但它不需要另一个查询来初始化变量;它可以嵌入到更复杂的查询中。 它返回用分号分隔的所有 'field2'。

SELECT result
FROM   (SELECT @result := '',
               (SELECT result
                FROM   (SELECT @result := CONCAT_WS(';', @result, field2) AS result,
                               LENGTH(@result)                            AS blength
                        FROM   some_table
                        ORDER  BY blength DESC
                        LIMIT  1) AS sub1) AS result) AS sub2; 

【讨论】:

这是一个很好的答案,但还没有完成这个问题 - 这是如何获得一个很长的连接,但是分组呢?您的查询只返回一行,而不是每组一行。 我记得这就是我试图做的——将整个结果集放入一个字符串中。 @Benubird 这是一个非常糟糕的查询。坏我的意思是可怕的。 OP 正在执行一个相关子查询,该子查询在子查询内有一个子查询。如果您要通过数据比较来检查这一点,您将在他的样本数据集上进行 256 次比较,也就是 4 行。现在想象一下,如果您有 1k 行,那就是 1 万亿次比较。 @JohnRuddell 是的。我可以向你保证,这个查询在一个严肃的实时系统中是远远不够的。当时,我需要它来进行某种挑战/练习。 啊,明白了..我建议您为其他路人记下这一点...因为这个答案会误导:) 不过有趣的尝试【参考方案7】:

简短的回答:需要在建立与 MySQL 服务器的连接时进行设置。例如,如果使用 MYSQLi / PHP,它将看起来像这样:

$ myConn = mysqli_init(); 
$ myConn->options(MYSQLI_INIT_COMMAND, 'SET SESSION group_concat_max_len = 1000000');

因此,如果您使用的是自制框架,那么您需要在建立连接时寻找代码中的位置并提供合理的值。

2020年我还在用Codeigniter 3,所以在这个框架中,要添加的代码在application/system/database/drivers/mysqli/mysqli_driver.php中,函数名为db_connect();

public function db_connect($persistent = FALSE)
    
        // Do we have a socket path?
        if ($this->hostname[0] === '/')
        
            $hostname = NULL;
            $port = NULL;
            $socket = $this->hostname;
        
        else
        
            $hostname = ($persistent === TRUE)
                ? 'p:'.$this->hostname : $this->hostname;
            $port = empty($this->port) ? NULL : $this->port;
            $socket = NULL;
        

        $client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0;
        $this->_mysqli = mysqli_init();

        $this->_mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10);
        $this->_mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION group_concat_max_len = 1000000');

...
    

【讨论】:

以上是关于MySQL 和 GROUP_CONCAT() 最大长度的主要内容,如果未能解决你的问题,请参考以下文章

解决mysql中group_concat长度限制的方案

Mysql 中的group_concat函数的使用及陷阱

Mysql 中的group_concat函数的使用及陷阱

MySQL 中 CSV 格式的 GROUP_CONCAT

MySQL中使用group_concat遇到的坑

Warning: (1260, 'Row xxx was cut by GROUP_CONCAT()')