let's try using the SUBSTRING_INDEX
function
SELECT SUBSTRING_INDEX(t.customer_id,',',1) AS c1
, SUBSTRING_INDEX(t.customer_id,',',2) AS c2
, SUBSTRING_INDEX(t.customer_id,',',3) AS c3
, SUBSTRING_INDEX(t.customer_id,',',4) AS c4
FROM ( SELECT 1 AS id, 'A' AS `type`, '456,484,234' AS customer_id
UNION ALL SELECT 2, 'B', '235,659,456'
) t
returns
c1 c2 c3 c4
------ ------- ----------- -------------
456 456,484 456,484,234 456,484,234
235 235,659 235,659,456 235,659,456
let's try adding another SUBSTRING_INDEX
with -1
parameter
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.customer_id,',',1),',',-1) AS c1
, SUBSTRING_INDEX(SUBSTRING_INDEX(t.customer_id,',',2),',',-1) AS c2
, SUBSTRING_INDEX(SUBSTRING_INDEX(t.customer_id,',',3),',',-1) AS c3
, SUBSTRING_INDEX(SUBSTRING_INDEX(t.customer_id,',',4),',',-1) AS c4
FROM ( SELECT 1 AS id, 'A' AS `type`, '456,484,234' AS customer_id
UNION ALL SELECT 2, 'B', '235,659,456'
) t
returns
c1 c2 c3 c4
---- ---- ---- ----
456 484 234 234
235 659 456 456
let's append an extra comma before we do the SUBSTRING_INDEX
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(t.customer_id,','),',',1),',',-1) AS c1
, SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(t.customer_id,','),',',2),',',-1) AS c2
, SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(t.customer_id,','),',',3),',',-1) AS c3
, SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(t.customer_id,','),',',4),',',-1) AS c4
FROM ( SELECT 1 AS id, 'A' AS `type`, '456,484,234' AS customer_id
UNION ALL SELECT 2, 'B', '235,659,456'
) t
c1 c2 c3 c4
---- ---- ---- ----
456 484 234
235 659 456
lets generate separate rows, and discard rows that have empty string:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(t.customer_id,','),',',i.n),',',-1) AS cn
FROM ( SELECT 1 AS id, 'A' AS `type`, '456,484,234' AS customer_id
UNION ALL SELECT 2, 'B', '235,659,456'
) t
CROSS
JOIN ( SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 ) i
HAVING cn <> ''
returns
cn
----
456
235
484
659
234
456
we can add expressions to the SELECT list
SELECT t.id
, t.type
, SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(t.customer_id,','),',',i.n),',',-1) AS cn
FROM ( SELECT 1 AS id, 'A' AS `type`, '456,484,234' AS customer_id
UNION ALL SELECT 2, 'B', '235,659,456'
) t
CROSS
JOIN ( SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 ) i
HAVING cn <> ''
ORDER BY t.id, t.type, i.n
returns
id type cn
-- ----- ----
1 A 456
1 A 484
1 A 234
2 B 235
2 B 659
2 B 456
to generate sequential values for the id
, we can wrap that query as an inline view, and use user-defined variables to generate values
SELECT (@id := @id + 1) AS id
, v.type
, v.cn
FROM (
SELECT t.id
, t.type
, SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(t.customer_id,','),',',i.n),',',-1) AS cn
FROM ( SELECT 1 AS id, 'A' AS `type`, '456,484,234' AS customer_id
UNION ALL SELECT 2, 'B', '235,659,456'
) t
CROSS
JOIN ( SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 ) i
HAVING cn <> ''
ORDER BY t.id, t.type, i.n
) v
CROSS
JOIN ( SELECT @id := 0 ) j
returns
id type cn
-- ----- ----
1 A 456
2 A 484
3 A 234
4 B 235
5 B 659
6 B 456