2009-06-04 8 views
1

Voici une question délicate.Regroupement MySQL avec un champ séparé par des virgules

Je contiennent des données comme suit:

 
User ID Name  Skill Sets 
1  Jim  Install, Configure 
2  Jack  Install 
3  John  Configure, Setup, Blah 
4  Bill  Setup, Install 

Ce n'est pas ma conception, et ce n'est pas une option pour changer la façon dont les données sont formatées. Le problème est que je dois regrouper par les ensembles de compétences uniques. De toute évidence, un groupe de droite me donne maintenant:

 
Skill Set    Count 
Install, Configure  1 
Install     1 
Configure, Setup, Blah 1 
Setup, Install   1 

souhaitée est sortie:

 
Skill Set Count 
Install  3 
Configure 2 
Setup  2 
Blah   1 

Des idées? Je pourrais théoriquement faire une vue qui sépare les ensembles de compétences dans une forme normalisée (comme il se doit). Mais je ne suis pas positif sur la syntaxe pour cela non plus.

+0

L'ensemble des compétences possibles est-il bien défini, ou devez-vous passer par «tout ce qui apparaît n'importe où dans un champ d'ensemble de compétences»? – balpha

+0

Les compétences sont bien définies dans un tableau séparé. Ils ont simplement choisi de concaténer la chaîne au lieu d'utiliser une table relationnelle appropriée. Les données sont de la merde, bien sûr, parce qu'il y avait des fautes de frappe dans certains noms de compétences qui ont été changés. Je peux accepter d'avoir "Installer" et "Instla" en tant que groupes séparés bien que pour l'instant. –

Répondre

7

Vous devez avoir un jeu de lignes contenant toutes les valeurs possibles de vos compétences. Il manque un moyen de le faire, donc vous devrez le générer d'une manière ou d'une autre.

Si vous avez un tel resultset, question simplement:

SELECT skill, COUNT(*) 
FROM (
     SELECT 'Install' AS skill 
     UNION ALL 
     SELECT 'Configure' AS skill 
     UNION ALL 
     SELECT 'Setup' AS skill 
     UNION ALL 
     SELECT 'Blah' AS skill 
     ) s 
JOIN users u 
ON  find_in_set(s.skill, u.sets) 
GROUP BY 
     s.skill 

Puisque vous avez mentionné que vous avez vos compétences dans une table séparée, utilisez cette table:

SELECT skill, COUNT(*) 
FROM skills s 
JOIN users u 
ON  find_in_set(s.skill, u.sets) 
GROUP BY 
     s.skill 

Ceci, cependant, sera ne correspond jamais aux fautes de frappe, ils seront simplement sautés.

+0

À première vue, il semble que cela me donnera le nombre de compétences que chaque utilisateur possède, par opposition au nombre d'utilisateurs que chaque compétence a. Pourtant, le concept est le même (je pense). Je vais donner un coup de feu. –

+0

@epalla: oui, vous avez raison, mise à jour. – Quassnoi

+1

Fonctionne bien, merci Quassnoi! le "find_in_set" était le chaînon manquant pour moi. –

Questions connexes