2010-06-21 17 views
122

Ich mache SELECT GROUP_CONCAT(categories SEPARATOR ' ') FROM table. Beispieldaten unter:MySQL DISTINCT auf einem GROUP_CONCAT()

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

Aber ich bin immer test1 test2 test3 test4 test1 test3 zurück, und ich möchte test1 test2 test3 test4 zurück bekommen. Irgendwelche Ideen?

Vielen Dank!

Antwort

259

GROUP_CONCAT hat DISTINCT Attribut:

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

DISTINCT wird

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

REf arbeiten: - this

16

Andere Antworten auf diese Frage zurückkommen nicht die OP Bedürfnisse was, werden sie geben Sie eine Zeichenfolge wie folgt zurück:

test1 test2 test3 test1 test3 test4 

(beachten Sie, dass test1 und test3 dupliziert), während der OP diese Zeichenfolge zurückkehren will:

test1 test2 test3 test4 

das Problem hier ist, dass die Zeichenfolge "test1 test3" dupliziert und wird nur einmal eingesetzt, aber alle anderen sind voneinander unterschieden ("test1 test2 test3" ist anders als "test1 test3", auch wenn einige Tests in der gesamten Zeichenfolge doppelt vorhanden sind).

Was müssen wir hier tun, ist jede Zeichenfolge in verschiedene Reihen aufgeteilt, und wir müssen zuerst eine Zahlen-Tabelle erstellen:

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

dann können wir diese Abfrage ausführen:

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; 

und wir erhalten ein Ergebnis wie folgt:

test1 
test4 
test1 
test1 
test2 
test3 
test3 
test3 

und dann können wir GROUP_CONCAT Aggregatfunktion, uns anwenden DISTINCT-Klausel ing:

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; 

Bitte sehen Geige here.

+0

Es scheint, dass Ihre Interpretation der OP-Frage richtig ist; Ich denke jedoch, es sollte darauf hingewiesen werden, dass die Normalisierung der Daten durch Erstellung einer "blah_to_categories" - und einer "categories" -Tabelle für die entsprechende Viele-zu-Viele-Beziehung hier die beste Vorgehensweise wäre und viel Flexibilität hinzufügen würde. Dennoch ist Ihre Antwort eine kluge Lösung für jeden, der ein solches denormalisiertes Schema erbt. Es könnte auch dazu geeignet sein, eine Migration vom alten zum normalisierten Schema zu generieren. – 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; 

Dies wird verschiedene Werte zurück wie: test1, test2, test4, test3

1

Ich weiß, diese Frage ist alt, aber ich fühle mich wie das erwähnt werden sollte: Group_concat mit deutlichen = Leistungskiller. Wenn Sie in kleinen Datenbanken arbeiten, werden Sie nicht bemerken, aber wenn es skaliert - es wird nicht sehr gut funktionieren.

+1

Ich arbeite mit einer 10 Millionen Zeile Tabelle und meine Abfrage dauert die gleiche Zeit mit oder ohne DISTINCT. Ich verwende InnoDB. – ashishduh

+0

Welcher Datentyp? Wie viele Spalten? In meiner DB ist es schwer auf große Textfelder und es gibt etwa 30 einige ungerade Spalten mit unterschiedlichen. Das Abziehen von distinct alleine beschleunigt es drastisch, und es verwendet Innodb. – photocode