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

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

SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;

Мой результат:

shopping
fishing
coding

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

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

shopping, fishing, coding

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

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

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

Я только что написал небольшую демонстрацию того, как использовать group_concat, которая может быть вам полезна: giombetti.com/2013/06/06/mysql-group_concat

Marc Giombetti 06.06.2013 22:26

это может вам помочь w3resource.com/mysql/aggregate-functions-and-grouping/…

Aasif khan 13.01.2021 15:50
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1 300
2
725 699
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Ответ принят как подходящий

Вы можете использовать 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);

Просто имейте в виду ограничение в 1024 байта в результирующем столбце (см. Параметр group_concat_max_len)

Dag 28.03.2012 14:09

А добавив параметр DISTINCT, дублей не получишь. ... GROUP_CONCAT(DISTINCT hobbies)

Ludwig 18.06.2012 18:39

Мне нужно было получить ВСЕ данные из одного столбца. Не используйте для этого предложение GROUP BY. Пример: SELECT GROUP_CONCAT (электронная почта SEPARATOR ',') ОТ пользователей;

Jonathan Bergeron 17.01.2014 18:04

Если вы хотите отсортировать хобби в получившейся взорванной строке, используйте: SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ') FROM peoples_hobbies GROUP BY person_id

Jan 08.03.2017 18:38
GROUP_CONCAT также существует в SQLite и сделал мне день! Итак, +1!
sergiol 05.07.2018 20:32

Если вы попытаетесь использовать group_concat в строке с одним столбцом NULL, вся строка будет исключена из group_concat. Смотрите второй нюанс здесь.

MatrixManAtYrService 16.07.2018 23:06

Если им просто нужен список, нужно ли вообще выбирать и группировать person_id?

Kurucu 23.01.2019 06:35

Group_concat может достигнуть предела. Есть ли другой путь?

Ngô Văn Quyền 05.08.2020 05:23

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

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

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

  SELECT GROUP_CONCAT(hobbies SEPARATOR ', ') 
  FROM peoples_hobbies 
  WHERE person_id = 5 
  GROUP BY 'all';

Я думаю, что group by 'all' не нужен (тем более нежелателен), потому что он присваивает всем строкам строку all, а затем сравнивает строки между этими строками. Я прав?

Krzysiek 19.10.2014 22:43

Я полагаю, вы можете просто использовать выражение «GROUP BY NULL» ???

user251433 27.10.2020 17:36

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

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

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

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

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

test1,test11

это быстрее, чем GROUP_CONCAT?

jave.web 06.02.2014 22:39

Я тестировал это в PHPMyAdmin с сервером MySQL v5.6.17 в столбце описание (varchar (50)) в таблице тестовое задание, но он возвращает поле BLOB для каждой записи: SELECT @logmsg := CONCAT_ws(',',@logmsg,description) from test

Jan 08.03.2017 18:31

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

SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table

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

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

Дано:

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

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

+------------+--------------------+-------+
| 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 |
+------------------------------------------------+-------+

Хотя это хороший ответ, это больше похоже на рекламу, чем на простой ответ. Тем не менее, хороший хорошо сформулированный ответ.

FliiFe 15.11.2016 20:55

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

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;

Вот что я получил: «Нераспознанный тип оператора. (рядом с "DECLARE" в позиции 0) '

Istiaque Ahmed 07.11.2017 20:58

У меня был более сложный запрос, и я обнаружил, что мне пришлось использовать 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;

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

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

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

Или же

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

Для тех, кто ищет здесь, как использовать 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 нужно использовать внутри подзапроса, а не обертывать его.

Другие вопросы по теме