MySQL DISTINCT su un GROUP_CONCAT ()


186

Lo sto facendo SELECT GROUP_CONCAT(categories SEPARATOR ' ') FROM table. Dati di esempio di seguito:

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

Tuttavia, sto test1 test2 test3 test4 test1 test3tornando e vorrei test1 test2 test3 test4tornare. Qualche idea?

Grazie molto!

Risposte:


364

GROUP_CONCAT ha l'attributo DISTINCT:

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

48

L'uso di DISTINCT funzionerà

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

REf: - questo


20

DISTINCT: ti darà valori unici.

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

17

Altre risposte a questa domanda non restituiscono ciò di cui l'OP ha bisogno, restituiranno una stringa come:

test1 test2 test3 test1 test3 test4

(notare che test1e test3sono duplicati) mentre l'OP vuole restituire questa stringa:

test1 test2 test3 test4

il problema qui è che la stringa "test1 test3"è duplicata e viene inserita una sola volta, ma tutte le altre sono distinte tra loro ( "test1 test2 test3"è diversa "test1 test3", anche se alcuni test contenuti nell'intera stringa sono duplicati).

Quello che dobbiamo fare qui è dividere ogni stringa in righe diverse e dobbiamo prima creare una tabella numerica:

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

allora possiamo eseguire questa query:

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;

e otteniamo un risultato come questo:

test1
test4
test1
test1
test2
test3
test3
test3

e quindi possiamo applicare la funzione aggregata GROUP_CONCAT, usando la clausola 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;

Si prega di vedere il violino qui .


Sembra che la tua interpretazione della domanda di OP possa essere corretta; tuttavia, penso che dovrebbe essere sottolineato che la normalizzazione dei dati creando una "blah_to_categories" e una tabella "categorie" per la relazione molti-a-molti appropriata sarebbe la migliore pratica qui e aggiungerebbe molta flessibilità. Tuttavia, la tua risposta è una soluzione intelligente per chiunque erediti un tale schema denormalizzato. Probabilmente potrebbe anche essere adattato allo scopo di generare una migrazione dallo schema vecchio a quello normalizzato.
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;   

Ciò restituirà valori distinti come: test1, test2, test4, test3


6

Puoi semplicemente aggiungere DISTINCT davanti.

SELECT GROUP_CONCAT(DISTINCT categories SEPARATOR ' ')

se vuoi ordinare,

SELECT GROUP_CONCAT(DISTINCT categories ORDER BY categories ASC SEPARATOR ' ')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.