Могу ли я объединить несколько строк MySQL в одно поле?

Используя MySQL, я могу сделать что-то вроде:

SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;

Мои результаты:

shopping
fishing
coding

но вместо этого мне просто нужна 1 строка, 1 столбец:

Ожидаемый результат:

shopping, fishing, coding

Причина в том, что я выбираю несколько значений из нескольких таблиц, и после всех объединений у меня гораздо больше строк, чем хотелось бы.

Я искал функцию в MySQL Doc и не похоже, что функции CONCAT или CONCAT_WS принимают наборы результатов.

Кто-нибудь здесь знает, как это сделать?


person Dean Rather    schedule 10.11.2008    source источник
comment
Я только что написал небольшую демонстрацию того, как использовать group_concat, которая может быть вам полезна: giombetti.com/2013/06/06/mysql-group_concat   -  person Marc Giombetti    schedule 06.06.2013
comment
это может помочь вам w3resource. ru / mysql / aggregate-functions-and-grouping /   -  person Aasif khan    schedule 13.01.2021


Ответы (12)


Вы можете использовать GROUP_CONCAT:

SELECT person_id,
   GROUP_CONCAT(hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

Как заявил Людвиг в своем комментарии, вы можно добавить оператор DISTINCT, чтобы избежать дублирования:

SELECT person_id,
   GROUP_CONCAT(DISTINCT hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

Как заявил Ян в их комментарии, вы также можно отсортировать значения перед его сжатием с помощью ORDER BY:

SELECT person_id, 
       GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

Как заявил Даг в своем комментарии , Максимальный размер результата составляет 1024 байта. Чтобы решить эту проблему, запустите этот запрос перед запросом:

SET group_concat_max_len = 2048;

Конечно, вы можете изменить 2048 по своему усмотрению. Чтобы вычислить и присвоить значение:

SET group_concat_max_len = CAST(
                     (SELECT SUM(LENGTH(hobbies)) + COUNT(*) * LENGTH(', ')
                           FROM peoples_hobbies
                           GROUP BY person_id) AS UNSIGNED);
person Community    schedule 10.11.2008
comment
Просто имейте в виду ограничение в 1024 байта в результирующем столбце (см. Параметр group_concat_max_len) - person Dag; 28.03.2012
comment
А добавив параметр DISTINCT, дублей не получишь. ... GROUP_CONCAT(DISTINCT hobbies) - person Ludwig; 18.06.2012

Посмотрите GROUP_CONCAT, поддерживает ли ваша версия MySQL (4.1). Дополнительную информацию см. В документации. Детали.

Это выглядело бы примерно так:

  SELECT GROUP_CONCAT(hobbies SEPARATOR ', ') 
  FROM peoples_hobbies 
  WHERE person_id = 5 
  GROUP BY 'all';
person lpfavreau    schedule 10.11.2008
comment
Я думаю, что group by 'all' не является необходимым (тем более нежелательным), потому что это присваивает всем строкам строку all, а затем сравнивает строки между этими строками. Я прав? - person Krzysiek; 19.10.2014

Альтернативный синтаксис для объединения нескольких отдельных строк

ВНИМАНИЕ: этот пост вызовет у вас чувство голода.

Данный:

Я обнаружил, что хочу выбрать несколько отдельных строк вместо группы и объединить их в определенное поле.

Допустим, у вас есть таблица идентификаторов продуктов, их названий и цен:

+------------+--------------------+-------+
| product_id | name               | price |
+------------+--------------------+-------+
|         13 | Double Double      |     5 |
|         14 | Neapolitan Shake   |     2 |
|         15 | Animal Style Fries |     3 |
|         16 | Root Beer          |     2 |
|         17 | Lame T-Shirt       |    15 |
+------------+--------------------+-------+

Затем у вас есть какой-то причудливый ajax, в котором этих щенков отмечены флажками.

Ваш голодный бегемот выбирает 13, 15, 16. Сегодня ей нет десерта ...

Находить:

Способ суммировать порядок вашего пользователя в одной строке с помощью чистого mysql.

Решение:

Используйте GROUP_CONCAT с предложением IN:

mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary FROM product WHERE product_id IN (13, 15, 16);

Какие выходы:

+------------------------------------------------+
| order_summary                                  |
+------------------------------------------------+
| Double Double + Animal Style Fries + Root Beer |
+------------------------------------------------+

Бонусное решение:

Если вам нужна и общая цена, добавьте SUM():

mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary, SUM(price) AS total FROM product WHERE product_id IN (13, 15, 16);
+------------------------------------------------+-------+
| order_summary                                  | total |
+------------------------------------------------+-------+
| Double Double + Animal Style Fries + Root Beer |    10 |
+------------------------------------------------+-------+
person elbowlobstercowstand    schedule 23.09.2014
comment
Хотя это хороший ответ, это больше похоже на рекламу, чем на простой ответ. Тем не менее, хороший хорошо сформулированный ответ. - person FliiFe; 15.11.2016

Вы можете изменить максимальную длину значения GROUP_CONCAT, установив параметр group_concat_max_len.

Подробности см. В документации MySQL.

person pau.moreno    schedule 08.04.2010

Есть функция агрегирования GROUP, GROUP_CONCAT .

person Dean Rather    schedule 10.11.2008

В моем случае у меня была строка идентификаторов, и необходимо было преобразовать ее в char, иначе результат был закодирован в двоичный формат:

SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table
person Fedir RYKHTIK    schedule 10.06.2014

Используйте переменную сеанса MySQL (5.6.13) и оператор присваивания, как показано ниже

SELECT @logmsg := CONCAT_ws(',',@logmsg,items) FROM temp_SplitFields a;

тогда вы можете получить

test1,test11
person Shen liang    schedule 27.09.2013
comment
это быстрее, чем GROUP_CONCAT? - person jave.web; 06.02.2014
comment
Я тестировал это в PHPMyAdmin с сервером MySQL v5.6.17 в столбце description (varchar (50)) в таблице test, но он возвращает поле BLOB для каждой записи: SELECT @logmsg := CONCAT_ws(',',@logmsg,description) from test - person Jan; 08.03.2017

У меня был более сложный запрос, и я обнаружил, что мне пришлось использовать GROUP_CONCAT во внешнем запросе, чтобы заставить его работать:

Исходный запрос:

SELECT DISTINCT userID 
FROM event GROUP BY userID 
HAVING count(distinct(cohort))=2);

Взорван:

SELECT GROUP_CONCAT(sub.userID SEPARATOR ', ') 
FROM (SELECT DISTINCT userID FROM event 
GROUP BY userID HAVING count(distinct(cohort))=2) as sub;

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

person Alex Bowyer    schedule 29.04.2015

Для тех, кто ищет здесь, как использовать GROUP_CONCAT с подзапросом - публикация этого примера

SELECT i.*,
(SELECT GROUP_CONCAT(userid) FROM favourites f WHERE f.itemid = i.id) AS idlist
FROM items i
WHERE i.id = $someid

Поэтому GROUP_CONCAT нужно использовать внутри подзапроса, а не обертывать его.

person Oleg Abrazhaev    schedule 26.04.2019

Попробуй это:

DECLARE @Hobbies NVARCHAR(200) = ' '

SELECT @Hobbies = @Hobbies + hobbies + ',' FROM peoples_hobbies WHERE person_id = 5;

TL;DR;

set @sql='';
set @result='';
set @separator=' union \r\n';
SELECT 
@sql:=concat('select ''',INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME  ,''' as col_name,',
INFORMATION_SCHEMA.COLUMNS.CHARACTER_MAXIMUM_LENGTH ,' as def_len ,' ,
'MAX(CHAR_LENGTH(',INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME , '))as  max_char_len',
' FROM ',
INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
) as sql_piece, if(@result:=if(@result='',@sql,concat(@result,@separator,@sql)),'','') as dummy
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE 
INFORMATION_SCHEMA.COLUMNS.DATA_TYPE like '%char%'
and INFORMATION_SCHEMA.COLUMNS.TABLE_SCHEMA='xxx' 
and INFORMATION_SCHEMA.COLUMNS.TABLE_NAME='yyy';
select @result;
person thejustv    schedule 26.02.2015
comment
Вот что я получил: «Нераспознанный тип оператора. (рядом с DECLARE в позиции 0) ' - person Istiaque Ahmed; 07.11.2017

у нас есть два способа объединить столбцы в MySql

select concat(hobbies) as `Hobbies` from people_hobbies where 1

Or

select group_concat(hobbies) as `Hobbies` from people_hobbies where 1
person raghavendra    schedule 13.11.2018

Уже поздно, но это будет полезно для тех, кто ищет объединение нескольких строк MySQL в одно поле с помощью сводной таблицы :)

Запрос:

SELECT pm.id, pm.name, GROUP_CONCAT(c.name) as channel_names
FROM payment_methods pm
LEFT JOIN payment_methods_channels_pivot pmcp ON pmcp.payment_method_id = pm.id
LEFT JOIN channels c ON c.id = pmcp.channel_id
GROUP BY pm.id

Таблицы

payment_methods 
  id  | name
  1   | PayPal

channels
  id  | name
  1   | Google
  2   | Faceook

payment_methods_channels_pivot
   payment_method_id | channel_id
   1                 |  1
   1                 |  2

Выход:

введите описание изображения здесь

person Muhammad Shahzad    schedule 13.07.2021