【问题标题】:GROUP_CONCAT() row count when grouping by a text field按文本字段分组时的 GROUP_CONCAT() 行数
【发布时间】:2012-10-03 11:59:05
【问题描述】:
DROP TABLE IF EXISTS `table`;
CREATE TABLE `table` (
  `id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
  `text` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `table` VALUES ('1', 'Unpacked reserved sir offering bed judgment may and quitting speaking. Is do be improved raptures offering required in replying raillery. Stairs ladies friend by in mutual an no. Mr hence chief he cause. Whole no doors on hoped. Mile tell if help they ye full name. \r\n\r\nLadyship it daughter securing procured or am moreover mr. Put sir she exercise vicinity cheerful wondered. Continual say suspicion provision you neglected sir curiosity unwilling. Simplicity end themselves increasing led day sympathize yet. General windows effects not are drawing man garrets. Common indeed garden you his ladies out yet. Preference imprudence contrasted to remarkably in on. Taken now you him trees tears any. Her object giving end sister except oppose. \r\n\r\nWas justice improve age article between. No projection as up preference reasonably delightful celebrated. Preserved and abilities assurance tolerably breakfast use saw. And painted letters forming far village elderly compact. Her rest west each spot his and you knew. Estate gay wooded depart six far her. Of we be have it lose gate bred. Do separate removing or expenses in. Had covered but evident chapter matters anxious.');
INSERT INTO `table` VALUES ('2', 'Unpacked reserved sir offering bed judgment may and quitting speaking. Is do be improved raptures offering required in replying raillery. Stairs ladies friend by in mutual an no. Mr hence chief he cause. Whole no doors on hoped. Mile tell if help they ye full name. \r\n\r\nLadyship it daughter securing procured or am moreover mr. Put sir she exercise vicinity cheerful wondered. Continual say suspicion provision you neglected sir curiosity unwilling. Simplicity end themselves increasing led day sympathize yet. General windows effects not are drawing man garrets. Common indeed garden you his ladies out yet. Preference imprudence contrasted to remarkably in on. Taken now you him trees tears any. Her object giving end sister except oppose. \r\n\r\nWas justice improve age article between. No projection as up preference reasonably delightful celebrated. Preserved and abilities assurance tolerably breakfast use saw. And painted letters forming far village elderly compact. Her rest west each spot his and you knew. Estate gay wooded depart six far her. Of we be have it lose gate bred. Do separate removing or expenses in. Had covered but evident chapter matters anxious');

在不使用GROUP_CONCAT() 的情况下运行GROUP BY 查询时,结果集符合预期(显示两行,text 的每个变体各一行):

SELECT
    `text`
FROM
    `table`
GROUP BY
    `text`;

+-----------------------------------+
| text                              |
+-----------------------------------+
| Unpacked reserved sir offering... |
| Unpacked reserved sir offering... |
+-----------------------------------+
2 rows in set (0.02 sec)

但是,当使用GROUP_CONCAT() 运行相同的查询时,结果集与预期不符(显示一行包含两个id 字段的串联字符串):

SELECT
    GROUP_CONCAT(`id` SEPARATOR ', ') AS ids
FROM
    `table`
GROUP BY
    `text`;

+------+
| ids  |
+------+
| 1, 2 |
+------+
1 row in set (0.00 sec)

我的问题:

为什么使用GROUP_CONCAT() 会影响返回的行数?

我最初的假设是 GROUP_CONCAT_MAX_LEN 与它有关(我的设置为 1024)但肯定只会影响 GROUP_CONCAT(),而不是 GROUP BY(另外,正如您可能注意到的那样,我正在使用 @ 987654333@ 在id 字段上,而不是text 字段上,其结果甚至没有接近超过GROUP_CONCAT_MAX_LEN)。

【问题讨论】:

  • 我运行了你的 SQL,得到两行,分别包含 ids 1 和 2。所以我无法重现这个问题。最可能的问题(通常)是超出列大小并被截断的文本。
  • 您的 text 字段的值不同。
  • 是的,但是当我包含 GROUP_CONCAT() 时,我在结果集中得到一行而不是两行。
  • rjh:但是如何将函数添加到选定字段绕过/影响按条件分组?
  • 您的编辑:我假设 GROUP_CONCAT_MAX_LEN 值不适用于 GROUP BY,因此它返回两行,因为它不会截断它们。

标签: mysql select group-by group-concat


【解决方案1】:

您必须根据需要将 ma​​x_sort_length 更改为更高数量的会话或全局。默认情况下,它的值为 1024 字节,您的字符串包含 1170 字节数据。通过增加大小,它将为 GROUP_CONCAT 提供两行。

查看此链接max_sort_length

SELECT `text` FROM `table` GROUP BY `text`;

SET SESSION max_sort_length = 2000;
SELECT GROUP_CONCAT(`id` SEPARATOR ', ') AS ids FROM `table` GROUP BY `text`;

查看SQL FIDDLE DEMO

编辑: BLOBTEXT 值不能可靠地用于 GROUP BY ORDER BYDISTINCT。在这些情况下比较 BLOB 值时,仅使用前 ma​​x_sort_length 个字节。 ma​​x_sort_length 的默认值为 1024,可以在服务器启动时或运行时更改。

【讨论】:

  • 这确实解决了问题。你能解释一下为什么max_sort_limit 只在使用GROUP_CONCAT 时起作用吗?我曾想过,如果用于对结果集进行分组的数据长度有限制,那么无论您选择什么,它都会适用。
  • @MichaelRushton 检查此链接linuxtopia.org/online_books/database_guides/…
  • 谢谢,尽管据我了解,这个问题似乎暗示第一个查询(我使用GROUP_CONCAT())将 只返回一行——因为我仍在按超出 max_sort_length 的字段进行分组。
  • 基本上我明白为什么第二个查询返回一行了;我明白为什么第一个查询返回两个。
  • Group by 不使用 order by,但 group concat 使用您在 group by 中使用的默认 order by。因此,当它使用 order by 时,它会对数据进行排序并检查 1024 字节的数据,而不是检查整个数据。
【解决方案2】:

您似乎遇到了 MySQL 的默认 GROUP_CONCAT_MAX_LEN。您的字符串长度为 1178,这肯定超过了默认值 1024。这意味着,如果值的差异晚于 1024,MySQL 将简单地忽略它,因为前 1024 个字符完全相同。这是对 GROUP_CONCAT 行为的限制,而不是对 GROUP 的限制。

您可以在 MySQL 的 my.cnf 文件中将其放大。

更多详情请看这里:

http://www.coderanch.com/t/422632/JDBC/databases/increase-group-concat-max-len

【讨论】:

  • 绝对正确的答案,并且还假设:只有 1024 个字符被传递给 GROUP BY(默认情况下),但是您可以通过在行首进行更改来检查,结果将如您所料.
  • 不确定是不是这样。如果您将值截断到 1024 以下,则行为会继续。
  • 您不仅需要截断它们,还需要使它们独一无二。我试过了,它根据他的需要重新调整了两行。
  • 但是对选定字段执行函数肯定不应该减少(或增加)返回的行数?
  • 另外,我在id 上执行GROUP_CONCAT(),而不是text
猜你喜欢
  • 2021-02-15
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 2012-09-19
  • 1970-01-01
相关资源
最近更新 更多