2010-06-21 11 views
122

Sto facendo SELECT GROUP_CONCAT(categories SEPARATOR ' ') FROM table. Dati di esempio:MySQL DISTINCT su un GROUP_CONCAT()

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

Tuttavia, io sono sempre test1 test2 test3 test4 test1 test3 indietro e mi piacerebbe ottenere test1 test2 test3 test4 indietro. Qualche idea?

Grazie mille!

risposta

259

GROUP_CONCAT ha attributo distinte:

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

Usando DISTINCT funzionerà

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

Ref: - this

16

Altre risposte a questa domanda non restituiscono quali sono le esigenze OP, lo faranno restituire una stringa del tipo:

test1 test2 test3 test1 test3 test4 

(notare che test1 e test3 sono duplicate) mentre l'OP vuole tornare questa stringa:

test1 test2 test3 test4 

il problema qui è che la stringa "test1 test3" viene duplicato e viene inserito solo una volta, ma tutti gli altri sono distinti tra loro ("test1 test2 test3" è diverso da "test1 test3", anche se alcuni test contenuti nell'intera stringa sono duplicati).

Quello che dobbiamo fare è quello di dividere ogni stringa in righe diverse, e abbiamo prima bisogno di creare una tabella numeri:

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 simile a questo:

test1 
test4 
test1 
test1 
test2 
test3 
test3 
test3 

e quindi possiamo applicare funzione di aggregazione group_concat, noi ing 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 here.

+0

Sembra che la tua interpretazione della domanda dell'OP possa essere corretta; tuttavia, ritengo opportuno precisare che la normalizzazione dei dati creando una tabella "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 simile schema denormalizzato. Potrebbe anche essere adattato allo scopo di generare una migrazione dallo schema vecchio a quello normalizzato. – XP84

6
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

1

Mi rendo conto che questa domanda è vecchia, ma mi sento come questo dovrebbe essere menzionato: group_concat con distinta = prestazioni assassino. Se lavori su piccoli database, non te ne accorgi, ma quando si ridimensiona, non funzionerà molto bene.

+1

Sto lavorando con una tabella di 10 milioni di righe e la mia query prende lo stesso tempo con o senza DISTINCT. Sto usando InnoDB. – ashishduh

+0

Quale tipo di dati? Quante colonne? Nel mio DB, è pesante su grandi campi di testo e ci sono circa 30 alcune colonne dispari che usano distinti. Portare via distinto solo accelera drammaticamente, e sta usando Innodb. – photocode

Problemi correlati