Você pode fazer isso com esta declaração (não, não está bonito), assumindo que o nome da sua tabela é
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 = ''
;
Demonstração da instrução SELECT
Explicação
Basicamente, adaptei o método de peterm para fazer a divisão. Eu tive que remover o
*
externo primeiro por TRIM. Para permitir a string vazia como valor da coluna, adicionei a construção CASE, para eliminar esses valores. Se sua coluna tiver valores NULL, você poderá substituir o CASE por
SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
e
SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
A UNION (sem a palavra-chave ALL) desta construção nos dará a lista de valores de cores distintas e com GROUP BY id e GROUP_CONCAT obteremos a lista de valores separados por *. Por último, adicionamos um
*
à esquerda e à direita para corresponder às suas necessidades. Para a atualização, você precisa modificar o select, para que ele retorne apenas uma coluna com uma linha (com a cláusula where).
Observação
Conforme declarado por peterm, isso permitirá até 100 valores em sua lista de valores. Eu não acredito que você vai precisar de mais, mas se você precisar, então você tem que adaptar a geração dos números de acordo com suas necessidades.