Option 1: Recursive Query
with recursive
data as (select concat(names, ', ') names from mytable),
cte as (
select
substring(names, 1, locate(', ', names) - 1) word,
substring(names, locate(', ', names) + 2) names
from data
union all
select
substring(names, 1, locate(', ', names) - 1) word,
substring(names, locate(', ', names) + 2) names
from cte
where locate(', ', names) > 0
)
select word from cte
Option 2: Recursive CTE
with recursive cte as (
select ' ' as name, concat(names, ',') as names, 1 as lev
from t
union all
select substring_index(names, ',', 1),
substr(names, instr(names, ',') + 2), lev + 1
from cte
where names like '%,%'
)
select name
from cte
where lev > 1;
Option 3: CREATE PROCEDURE
create or replace procedure splitstring(
value TEXT,
delim VARCHAR(12)
)
BEGIN
with recursive
data as (select CONCAT(value,delim) as entries),
cte as (
select
substring(entries, 1, locate(delim, entries) - LENGTH(delim)) entry,
substring(entries, locate(delim, entries) + LENGTH(delim)) entries
from data
union all
select
substring(entries, 1, locate(delim, entries) - LENGTH(delim)) entry,
substring(entries, locate(delim, entries) + LENGTH(delim)) entries
from cte
where locate(delim, entries) > 0
)
select entry from cte where length(entry) > 0;
END
Option 4: SUBSTRING_INDEX
SELECT
TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(names,',',x.x),',',-1)) as name
FROM mytable
CROSS JOIN (SELECT 1 as x union all select 2 union all select 3 union all select 4) x
WHERE x.x <= LENGTH(names)-LENGTH(REPLACE(names,',',''))+1
Option 5: Recursive CTE with Space Handling
with recursive names_cleaned as (
select replace(replace(names, ', ', ','), ',', ', ') nc
from t),
cte as (
select ' ' as name, concat(nc, ',') as nc, 1 as lev
from names_cleaned
union all
select substring_index(nc, ',', 1),
substr(nc, instr(nc, ',') + 2), lev + 1
from cte
where nc like '%,%'
)
select name
from cte
where lev > 1;