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() 最大长度的主要内容,如果未能解决你的问题,请参考以下文章