MySQL DISTINCT在GROUP_CONCAT()上


185

我在做SELECT GROUP_CONCAT(categories SEPARATOR ' ') FROM table。以下示例数据:

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

但是,我要test1 test2 test3 test4 test1 test3回来了,我想test1 test2 test3 test4回来。有任何想法吗?

非常感谢!

Answers:



48

使用DISTINCT将有效

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

REf:- 这个



17

该问题的其他答案不返回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

然后我们可以使用DISTINCT子句应用GROUP_CONCAT聚合函数:

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;

请看这里的小提琴。


您对OP问题的解释似乎是正确的;但是,我认为应该指出的是,通过为适当的多对多关系创建“ blah_to_categories”和“ categories”表来规范化数据将是此处的最佳实践,并且会增加很多灵活性。但是,对于继承了这种非规范化架构的任何人,您的答案都是一个明智的解决方法。它也可能适用于从旧模式到规范化模式的迁移。
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;   

这将返回不同的值,例如:test1,test2,test4,test3


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.