263 votes

MySQL DISTINCT sur un GROUP_CONCAT()

Je fais SELECT GROUP_CONCAT(categories SEPARATOR ' ') FROM table . Exemple de données ci-dessous :

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

Cependant, j'obtiens test1 test2 test3 test4 test1 test3 et je voudrais obtenir test1 test2 test3 test4 dos. Des idées ?

Merci beaucoup !

468voto

Naktibalda Points 3896

GROUPE_CONCAT a l'attribut DISTINCT :

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

70voto

Salil Points 20300

L'utilisation de DISTINCT fonctionnera

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

REf:- ce

56voto

Goshika Mahesh Points 51

DISTINCT : vous donnera des valeurs uniques.

SELECT GROUP_CONCAT(DISTINCT(categories )) AS categories FROM table

24voto

fthiella Points 21512

Les autres réponses à cette question ne renvoient pas ce dont l'OP a besoin, elles renvoient une chaîne comme :

test1 test2 test3 test1 test3 test4

(remarquez que test1 y test3 sont dupliqués) alors que le PO veut retourner cette chaîne :

test1 test2 test3 test4

le problème ici est que la chaîne "test1 test3" est dupliqué et n'est inséré qu'une seule fois, mais tous les autres sont distincts les uns des autres ( "test1 test2 test3" est distinct de "test1 test3" même si certains tests contenus dans la chaîne entière sont dupliqués).

Ce que nous devons faire ici est de diviser chaque chaîne en différentes lignes, et nous devons d'abord créer une table de nombres :

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

alors nous pouvons exécuter cette requête :

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;

et on obtient un résultat comme celui-ci :

test1
test4
test1
test1
test2
test3
test3
test3

et ensuite nous pouvons appliquer la fonction d'agrégation GROUP_CONCAT, en utilisant la clause 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;

Veuillez voir le violon aquí .

2 votes

Il semble que votre interprétation de la question de l'OP soit correcte ; cependant, je pense qu'il faut souligner que la normalisation des données en créant une table "blah_to_categories" et une table "categories" pour la relation many-to-many appropriée serait la meilleure pratique ici, et ajouterait beaucoup de flexibilité. Néanmoins, votre réponse est une solution de contournement intelligente pour toute personne qui hérite d'un tel schéma dénormalisé. Elle pourrait aussi probablement être adaptée pour générer une migration de l'ancien schéma vers le schéma normalisé.

20voto

Vous pouvez simplement ajouter DISTINCT devant.

SELECT GROUP_CONCAT(DISTINCT categories SEPARATOR ' ')

si vous voulez faire un tri,

SELECT GROUP_CONCAT(DISTINCT categories ORDER BY categories ASC SEPARATOR ' ')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X