MySQL DISTINCT en un GROUP_CONCAT ()


186

Que estoy haciendo SELECT GROUP_CONCAT(categories SEPARATOR ' ') FROM table. Datos de muestra a continuación:

categories
----------
test1 test2 test3
test4
test1 test3
test1 test3

Sin embargo, estoy test1 test2 test3 test4 test1 test3volviendo y me gustaría test1 test2 test3 test4volver. ¿Algunas ideas?

¡Muchas gracias!

Respuestas:


364

GROUP_CONCAT tiene el atributo DISTINCT:

SELECT GROUP_CONCAT(DISTINCT categories ORDER BY categories ASC SEPARATOR ' ') FROM table

48

Usar DISTINCT funcionará

SELECT GROUP_CONCAT(DISTINCT(categories) SEPARATOR ' ') FROM table

REf: - esto


20

DISTINCT: le dará valores únicos.

SELECT GROUP_CONCAT(DISTINCT(categories )) AS categories FROM table

17

Otras respuestas a esta pregunta no devuelven lo que el OP necesita, devolverán una cadena como:

test1 test2 test3 test1 test3 test4

(observe eso test1y test3están duplicados) mientras el OP quiere devolver esta cadena:

test1 test2 test3 test4

El problema aquí es que la cadena "test1 test3"se duplica y se inserta solo una vez, pero todos los demás son distintos entre sí ( "test1 test2 test3"es distinto de"test1 test3" , incluso si algunas pruebas contenidas en la cadena completa están duplicadas).

Lo que tenemos que hacer aquí es dividir cada cadena en diferentes filas, y primero debemos crear una tabla de números:

CREATE TABLE numbers (n INT);
INSERT INTO numbers VALUES
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);

entonces podemos ejecutar esta consulta:

SELECT
  SUBSTRING_INDEX(
    SUBSTRING_INDEX(tableName.categories, ' ', numbers.n),
    ' ',
    -1) category
FROM
  numbers INNER JOIN tableName
  ON
    LENGTH(tableName.categories)>=
    LENGTH(REPLACE(tableName.categories, ' ', ''))+numbers.n-1;

y obtenemos un resultado como este:

test1
test4
test1
test1
test2
test3
test3
test3

y luego podemos aplicar la función agregada GROUP_CONCAT, usando la cláusula DISTINCT:

SELECT
  GROUP_CONCAT(DISTINCT category ORDER BY category SEPARATOR ' ')
FROM (
  SELECT
    SUBSTRING_INDEX(SUBSTRING_INDEX(tableName.categories, ' ', numbers.n), ' ', -1) category
  FROM
    numbers INNER JOIN tableName
    ON LENGTH(tableName.categories)>=LENGTH(REPLACE(tableName.categories, ' ', ''))+numbers.n-1
  ) s;

Por favor, vea el violín aquí .


Parece que su interpretación de la pregunta de OP puede ser correcta; sin embargo, creo que debería señalarse que la normalización de los datos mediante la creación de una tabla "blah_to_categories" y una "categorías" para la relación adecuada de muchos a muchos sería la mejor práctica aquí, y agregaría mucha flexibilidad. Aún así, su respuesta es una solución inteligente para cualquiera que herede un esquema tan desnormalizado. Probablemente también podría adaptarse para generar una migración del esquema anterior al normalizado.
XP84

11
SELECT
  GROUP_CONCAT(DISTINCT (category))
FROM (
  SELECT
    SUBSTRING_INDEX(SUBSTRING_INDEX(tableName.categories, ' ', numbers.n), ' ', -1) category
  FROM
    numbers INNER JOIN tableName
    ON LENGTH(tableName.categories)>=LENGTH(REPLACE(tableName.categories, ' ', ''))+numbers.n-1
  ) s;   

Esto devolverá valores distintos como: test1, test2, test4, test3


6

Simplemente puede agregar DISTINCT al frente.

SELECT GROUP_CONCAT(DISTINCT categories SEPARATOR ' ')

si quieres ordenar,

SELECT GROUP_CONCAT(DISTINCT categories ORDER BY categories ASC SEPARATOR ' ')
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.