2013-09-29 7 views
19

J'ai une colonne avec un nombre variable de valeurs séparées par des virgules:split SQL séparées par des virgules ligne

somethingA,somethingB,somethingC 
somethingElseA, somethingElseB 

Et je veux que le résultat de prendre chaque valeur et créer une ligne:

somethingA 
somethingB 
somethingC 
somethingElseA 
somethingElseB 

Comment puis-je faire cela en SQL (MySQL)?

(je l'ai essayé googler « imploser » et « vue latérale », mais ceux-ci ne semble pas se présenter aux questions connexes. Tous les associés SO des questions tentent de faire des choses beaucoup plus compliquées) Vous

+0

a demandé une fois gazillion sur SO: eghttp: //stackoverflow.com/questions/10581772/sql-server-2008-how-to-split-a-comma-separated-value-to-columns , http://stackoverflow.com/questions/13873701/convert-comma-separated-column-value-to-rows –

+1

@MitchWheat - ce n'est pas une réponse à cette question. Ils ont un certain nombre de valeurs séparées par des virgules, ce n'est pas le cas. –

+0

Vous cherchez une solution purement SQL, ou une solution dans une autre langue - comme PHP par exemple. –

Répondre

59

peut le faire avec SQL pur comme celui-ci

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.values, ',', n.n), ',', -1) value 
    FROM table1 t CROSS JOIN 
(
    SELECT a.N + b.N * 10 + 1 n 
    FROM 
    (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a 
    ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b 
    ORDER BY n 
) n 
WHERE n.n <= 1 + (LENGTH(t.values) - LENGTH(REPLACE(t.values, ',', ''))) 
ORDER BY value 

note: L'astuce consiste à tirer parti de compte (chiffres) table et un très pratique dans ce cas la fonction MySQL SUBSTRING_INDEX(). Si vous faites beaucoup de telles requêtes (fractionnement) alors vous pourriez envisager de remplir et d'utiliser une table de pointage persistante au lieu de la générer à la volée avec une sous-requête comme dans cet exemple. La sous-requête de cet exemple génère une séquence de nombres comprise entre 1 et 100, ce qui vous permet de diviser jusqu'à 100 valeurs délimitées par ligne dans la table source. Si vous en avez besoin plus ou moins, vous pouvez facilement l'ajuster.

Sortie:

 
|   VALUE | 
|----------------| 
|  somethingA | 
|  somethingB | 
|  somethingC | 
| somethingElseA | 
| somethingElseB | 

est ici SQLFiddle Démo


Voici comment la requête peut regarder avec une table de pointage persistant

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.values, ',', n.n), ',', -1) value 
    FROM table1 t CROSS JOIN tally n 
WHERE n.n <= 1 + (LENGTH(t.values) - LENGTH(REPLACE(t.values, ',', ''))) 
ORDER BY value 

est ici SQLFiddle démo

+1

Solution de génie. Je vous remercie. – bharatesh

+0

Grande réponse, a parfaitement fonctionné pour insérer des ID amis dans une table de relation utilisateur (basé sur la colonne contenant friendid1, friendid2) –

+0

Works. Astuce: Remplacez 'table1 -> [votre table]', 'values ​​-> votre nom de champ',' value -> votre nom de champ', rien d'autre n'est requis. –

Questions connexes