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

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

SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;

Мой вывод:

shopping
fishing
coding

но вместо этого я просто хочу 1 строку, 1 столбец:

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

shopping, fishing, coding

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

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

вопрос задан 10.11.2008
Dean Rather
17475 репутация

9 ответов


  • 1419 рейтинг

    Вы можете использовать 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
    )
    
    ответ дан che, с репутацией 9800, 10.11.2008
  • 79 рейтинг

    Посмотрите на GROUP_CONCAT, если ваша версия MySQL (4. 1) поддерживает это. См. документацию для более подробной информации.

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

      SELECT GROUP_CONCAT(hobbies SEPARATOR ', ') 
      FROM peoples_hobbies 
      WHERE person_id = 5 
      GROUP BY 'all';
    
    ответ дан lpfavreau, с репутацией 7933, 10.11.2008
  • 53 рейтинг

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

    ВНИМАНИЕ: Этот пост сделает вас голодным.

    Подарено:

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

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

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

    Тогда у вас есть какой-то необычный аякс, который перечисляет этих щенков как флажки.

    Ваш пользователь голодного бегемота выбирает 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 |
    +------------------------------------------------+-------+
    

    PS: Извините, если у вас нет In-N-Out поблизости. , ,

    ответ дан elbowlobstercowstand, с репутацией 2201, 23.09.2014
  • 34 рейтинг

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

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

    ответ дан pau.moreno, с репутацией 2501, 8.04.2010
  • 24 рейтинг

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

    ответ дан Dean Rather, с репутацией 17475, 10.11.2008
  • 19 рейтинг

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

    SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table
    
    ответ дан Fedir RYKHTIK, с репутацией 6905, 10.06.2014
  • 13 рейтинг

    Использовать MySQL (5. 6. 13) переменная сеанса и оператор присваивания, подобный следующему

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

    тогда можно получить

    test1,test11
    
    ответ дан Shen liang, с репутацией 842, 27.09.2013
  • 10 рейтинг

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

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

    ответ дан alexbfree, с репутацией 359, 29.04.2015
  • 5 рейтинг

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

    DECLARE @Hobbies NVARCHAR(200) = ' '
    
    SELECT @Hobbies = @Hobbies + hobbies + ',' FROM peoples_hobbies WHERE person_id = 5;
    
    ответ дан thejustv, с репутацией 1036, 26.02.2015