GROUP_CONCAT()でのMySQL DISTINCT


186

やって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ます。何か案は?

どうもありがとう!

回答:



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のような異なる値を返します。


6

前にDISTINCTを追加するだけです。

SELECT GROUP_CONCAT(DISTINCT categories SEPARATOR ' ')

並べ替える場合は

SELECT GROUP_CONCAT(DISTINCT categories ORDER BY categories ASC SEPARATOR ' ')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.