2010-06-21 218 views
122

我在做SELECT GROUP_CONCAT(categories SEPARATOR ' ') FROM table。下面的示例數據:MySQL DISTINCT在GROUP_CONCAT()上

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

但是,我越來越test1 test2 test3 test4 test1 test3回來了,我想獲得test1 test2 test3 test4回來。有任何想法嗎?

非常感謝!

回答

259

GROUP_CONCAT具有明顯的屬性:

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

使用DISTINCT將工作

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

REF: - this

16

對這個問題的其他答案不回什麼OP的需求,他們會返回一個字符串,如:

test1 test2 test3 test1 test3 test4 

(注意test1test3是重複的),而OP想要回這個字符串:

test1 test2 test3 test4 

這裏的問題是,串"test1 test3"被複制並插入只有一次,但所有的人都("test1 test2 test3""test1 test3"不同,即使包含在整個字符串中的某些測試重複)也是如此。

我們在這裏需要做的是給每個字符串分割成不同的行,我們首先需要創建一個數字表:

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

那麼我們就可以運行此查詢:

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; 

我們得到如下結果:

test1 
test4 
test1 
test1 
test2 
test3 
test3 
test3 

然後我們可以應用GROUP_CONCAT聚合函數,我們荷蘭國際集團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; 

請參閱小提琴here

+0

看來你對OP問題的解釋可能是對的;然而,我認爲應該指出的是,通過爲適當的多對多關係創建「blah_to_categories」和「類別」表來規範化數據將是最佳實踐,並且會增加很多靈活性。儘管如此,對於繼承這種非規範化模式的人來說,您的答案是一個明智的解決方法。它也可能適用於產生從舊模式向正常模式遷移的目的。 – XP84 2016-06-01 17:11:14

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; 

這將返回象不同的值:TEST1,TEST2,TEST4,TEST3

1

我意識到這個問題是舊的,但我覺得這應該被提及:具有鮮明=性能殺手GROUP_CONCAT。如果你在小型數據庫中工作,你不會注意到,但是當它擴展時 - 它不會工作得很好。

+1

我正在處理一個1000萬行的表,並且我的查詢需要同時處理或不處理DISTINCT。我正在使用InnoDB。 – ashishduh 2017-08-10 18:07:59

+0

什麼數據類型?多少列?在我的數據庫中,它在大型文本字段上很重,並且有大約30個使用不同的奇數列。單獨帶走獨特性顯着提高了速度,並使用Innodb。 – photocode 2017-08-11 10:23:39