Vous pouvez le faire avec cette déclaration (non, ça n'a pas l'air sympa), en supposant que le nom de votre table est example
:
UPDATE
example e1
SET
e1.type_a = (
SELECT
CONCAT('*', GROUP_CONCAT(DISTINCT n1.value ORDER BY n1.value SEPARATOR '*'), '*') as type_a
FROM (
SELECT
id,
CASE
WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1) = '' THEN NULL
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
END value
FROM example e CROSS JOIN (
SELECT
a.N + b.N * 10 + 1 AS 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(e.type_a) - LENGTH(REPLACE(e.type_a, '*', '')))
UNION
SELECT
id,
CASE
WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_b), '*', n.n), '*', -1) = '' THEN NULL
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_b), '*', n.n), '*', -1)
END value
FROM example e CROSS JOIN (
SELECT
a.N + b.N * 10 + 1 AS 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(e.type_b) - LENGTH(REPLACE(e.type_b, '*', '')))
) n1
WHERE
n1.id = e1.id
GROUP BY
id
),
e1.type_b = ''
;
Démo de l'instruction SELECT
Explication
En gros, j'ai adapté la méthode
de peterm
pour faire la séparation. J'ai dû supprimer le *
extérieur d'abord par TRIM.
Pour autoriser la chaîne vide comme valeur de colonne, j'ai ajouté la construction CASE, pour éliminer ces valeurs. Si votre colonne a des valeurs NULL à la place, vous pouvez remplacer le CASE par
SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
et
SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
L'UNION (sans le mot clé ALL) de cette construction nous donnera la liste des valeurs de couleur distinctes et avec GROUP BY id et GROUP_CONCAT nous obtiendrons la liste de valeurs séparées *. Enfin, nous ajoutons un *
de début et de fin pour répondre à vos besoins.
Pour la mise à jour, vous devez modifier la sélection, afin qu'elle renvoie une seule colonne avec une ligne (avec la clause where).
Remarque
Comme indiqué par peterm, cela autorisera jusqu'à 100 valeurs dans votre liste de valeurs. Je ne pense pas que vous en aurez besoin de plus, mais si vous voulez, alors vous devez adapter la génération des nombres à vos besoins.