Puedo concatenar varias filas MySQL en un campo?


Usando MySQL, puedo hacer algo como:

SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;

Mi Salida:

shopping
fishing
coding

Pero en lugar de eso solo quiero 1 fila, 1 col:

Producción prevista:

shopping, fishing, coding

La razón es que estoy seleccionando múltiples valores de varias tablas, y después de todas las uniones tengo muchas más filas de las que me gustaría.

He buscado una función en MySQL Doc y no parece que las funciones CONCAT o CONCAT_WS acepten conjuntos de resultados, por lo que cualquiera aquí sabe cómo hacer esto?

Author: DineshDB, 2008-11-10

9 answers

Puede utilizar GROUP_CONCAT:

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

Como Ludwig declaró en su comentario, puede agregar el operador DISTINCT para evitar duplicados:

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

Como Jan declaró en su comentario, también puede ordenar los valores antes de implosionar usando ORDER BY:

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

Como Dag declaró en su comentario, hay un límite de 1024 bytes en el resultado. Para resolver esto, ejecute esta consulta antes de su consulta:

SET group_concat_max_len = 2048

Por supuesto, puedes cambiar 2048 de acuerdo a tus necesidades. Para calcular y asignar el valor:

SET group_concat_max_len = CAST(
    (SELECT SUM(LENGTH(hobbies)) + COUNT(*) * LENGTH(', ')
    FROM peoples_hobbies GROUP BY person_id)
    AS UNSIGNED
)
 1424
Author: che,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-08 15:48:13

Eche un vistazo a GROUP_CONCAT si su versión de MySQL (4.1) lo soporta. Vea la documentación para más detalles.

Se vería algo así como:

  SELECT GROUP_CONCAT(hobbies SEPARATOR ', ') 
  FROM peoples_hobbies 
  WHERE person_id = 5 
  GROUP BY 'all';
 81
Author: lpfavreau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-01 08:13:19

Sintaxis alternativa para concatenar filas múltiples e individuales

ADVERTENCIA: Este post te dará hambre.

Dado:

Me encontré queriendo seleccionar múltiples filas individuales-en lugar de un grupo-y concatenar en un cierto campo.

Digamos que tienes una tabla de ID de producto y sus nombres y precios:

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

Entonces tienes un ajax elegante que enumera a estos cachorros como casillas de verificación.

Tu usuario hambriento de hipopótamos selecciona 13, 15, 16. Hoy no hay postre para ella...

Buscar:

Una forma de resumir el orden de su usuario en una línea, con mysql puro.

Solución:

Use GROUP_CONCAT con la cláusula IN :

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

Que produce:

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

Solución de bonificación:

Si usted quiere el precio total también, tirar en 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 |
+------------------------------------------------+-------+

PD: Disculpas si usted no tiene un In-N-Out cercano...

 54
Author: elbowlobstercowstand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-07 17:39:54

Puede cambiar la longitud máxima del valor GROUP_CONCAT configurando el parámetro group_concat_max_len.

Ver detalles en el MySQL documantation.

 34
Author: pau.moreno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-27 14:25:08

Hay una función GROUP Aggregate, GROUP_CONCAT.

 24
Author: Dean Rather,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-27 23:03:11

En mi caso tenía una fila de Ids, y era necesario convertirlo en char, de lo contrario, el resultado se codificó en formato binario:

SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table
 19
Author: Fedir RYKHTIK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-10 09:24:31

Use la variable de sesión MySQL(5.6.13) y el operador de asignación como el siguiente

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

Entonces puedes obtener

test1,test11
 13
Author: Shen liang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-27 18:47:25

Tuve una consulta más complicada, y descubrí que tenía que usar GROUP_CONCAT en una consulta externa para que funcionara:

Consulta original:

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

Implosionado:

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

Espero que esto pueda ayudar a alguien.

 10
Author: Alex Bowyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-29 16:35:34

Prueba esto:

DECLARE @Hobbies NVARCHAR(200) = ' '

SELECT @Hobbies = @Hobbies + hobbies + ',' FROM peoples_hobbies WHERE person_id = 5;
 6
Author: thejustv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-18 03:37:56