Как использовать GROUP BY для объединения строк в MySQL?

351

В основном вопрос заключается в том, как получить из этого:

foo_id foo_name
1 А
1 Б
2 C

к этому:

foo_id foo_name
1 АБ
2 C
Павел Хайдан
источник
13
ЗАГРУЗИТЬ действительно сложно ввести имя столбца, присвоив ему имя, похожее на тип данных. Таким образом, на любые ответы также влияет то, что ответы выглядят так, как будто они
задают
2
@barlop исправил это, отредактировав вопрос и ответы.
ustun

Ответы:

526
SELECT id, GROUP_CONCAT(name SEPARATOR ' ') FROM table GROUP BY id;

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

По приведенной выше ссылке GROUP_CONCAT: Эта функция возвращает строковый результат с объединенными ненулевыми значениями из группы. Возвращает NULL, если нет ненулевых значений.

Скотт Нойес
источник
164
SELECT id, GROUP_CONCAT( string SEPARATOR ' ') FROM table GROUP BY id

Подробнее здесь .

По приведенной выше ссылке GROUP_CONCAT: Эта функция возвращает строковый результат с объединенными ненулевыми значениями из группы. Возвращает NULL, если нет ненулевых значений.

Грэм Перроу
источник
результирующий столбец имеет ограничение в символах. смотрите здесь и документы :)
Марло
18
SELECT id, GROUP_CONCAT(CAST(name as CHAR)) FROM table GROUP BY id

Даст вам строку через запятую

Wayne
источник
17
SELECT id, GROUP_CONCAT(name SEPARATOR ' ') FROM table GROUP BY id;

: - В MySQL вы можете получить объединенные значения комбинаций выражений. Чтобы исключить повторяющиеся значения, используйте предложение DISTINCT . Чтобы отсортировать значения в результате, используйте предложение ORDER BY. Для сортировки в обратном порядке добавьте ключевое слово DESC (по убыванию) к имени столбца, по которому вы сортируете, в предложении ORDER BY. По умолчанию это возрастающий порядок; это может быть указано явно с помощью ключевого слова ASC. Разделителем по умолчанию между значениями в группе является запятая («,»). Чтобы явно указать разделитель, используйте SEPARATOR, за которым следует строковое литеральное значение, которое должно быть вставлено между значениями группы. Чтобы полностью удалить разделитель, укажите разделитель '' .

GROUP_CONCAT([DISTINCT] expr [,expr ...]
             [ORDER BY {unsigned_integer | col_name | expr}
                 [ASC | DESC] [,col_name ...]]
             [SEPARATOR str_val])

ИЛИ

mysql> SELECT student_name,
    ->     GROUP_CONCAT(DISTINCT test_score
    ->               ORDER BY test_score DESC SEPARATOR ' ')
    ->     FROM student
    ->     GROUP BY student_name;
Exundoz
источник
15

Результат усекается до максимальной длины, заданной системной переменной group_concat_max_len, которая имеет значение по умолчанию 1024 символа, поэтому сначала сделаем:

SET group_concat_max_len=100000000;

а затем, например:

SELECT pub_id,GROUP_CONCAT(cate_id SEPARATOR ' ') FROM book_mast GROUP BY pub_id
Вакар Аламгир
источник
Результат усекается до максимальной длины, заданной системной переменной group_concat_max_len со значением по умолчанию 1024 символа. документы
Марло
Каков охват этого group_concat_max_lenконфига? Текущее соединение / сеанс, или это повлияет на других клиентов?
Замороженное пламя
@FrozenFlame:> Если модификатор отсутствует, SET изменяет переменную сеанса. Если переменная не имеет значения сеанса, возникает ошибка. От dev.mysql.com/doc/refman/5.7/en/using-system-variables.html
arminrosu
3
Это не отвечает на вопрос ОП, а просто добавляет полезную информацию. Это должен быть комментарий, а не ответ.
Шон Боб
1
Спасибо за этот фрагмент кода, который может оказать некоторую ограниченную, немедленную помощь. Надлежащее объяснение будет значительно улучшить свою долгосрочную ценность, показывая , почему это является хорошим решением проблемы и сделает его более полезным для читателей будущих с другими подобными вопросами. Пожалуйста, измените свой ответ, чтобы добавить некоторые объяснения, в том числе предположения, которые вы сделали.
Дональд Дак
11

Отличные ответы. У меня также была проблема с NULLS, и мне удалось ее решить, добавив COALESCE в GROUP_CONCAT. Пример следующим образом:

SELECT id, GROUP_CONCAT(COALESCE(name,'') SEPARATOR ' ') 
FROM table 
GROUP BY id;

Надеюсь, это поможет кому-то еще

Маурисио Ало
источник