Razztak
asked on
Split Function in MySQL to Delimited string into Rows
Hello,
I have a table with ID and Keywords, in keywords field words is separate by ';'. iI want split each delimited sting into rows. Some rows have 1, 2, 3 to 6 or 7 word separated by ;.
Source Table:
ID keywords
-----------------------
38 RedeTV! ; Mônica Pimentel
39 Rádio Show
40 Alexandre Pires
41 Famosos
42 Band
43 Camila Tittinger ; All TV ; Band ; Show
Result Table:
ID keywords
-----------------------
38 RedeTV!
38 Mônica Pimentel
39 Rádio Show
40 Alexandre Pires
41 Famosos
42 Band
43 Camila Tittinger
43 All TV
43 Band
43 Show
Of course i need the script work in MySQL 5.x
Thanks in Advance,
I have a table with ID and Keywords, in keywords field words is separate by ';'. iI want split each delimited sting into rows. Some rows have 1, 2, 3 to 6 or 7 word separated by ;.
Source Table:
ID keywords
-----------------------
38 RedeTV! ; Mônica Pimentel
39 Rádio Show
40 Alexandre Pires
41 Famosos
42 Band
43 Camila Tittinger ; All TV ; Band ; Show
Result Table:
ID keywords
-----------------------
38 RedeTV!
38 Mônica Pimentel
39 Rádio Show
40 Alexandre Pires
41 Famosos
42 Band
43 Camila Tittinger
43 All TV
43 Band
43 Show
Of course i need the script work in MySQL 5.x
Thanks in Advance,
Here is the quick procedure.
I have a "tmp" table with column "cat" with ";" separated values.
Following method will insert all values into other table after splitting "cat" values by ";".
1. create table:
CREATE TABLE `my_splits` (
`splitted_column` varchar(45) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
2. create procedure.
3. execute procedure.
4. check table my_splits.
* you may update it with your ID specific requirements, I suppose it'd be easy or may be you can do that using join+find in set query.
Happy Weekend!!
I have a "tmp" table with column "cat" with ";" separated values.
Following method will insert all values into other table after splitting "cat" values by ";".
1. create table:
CREATE TABLE `my_splits` (
`splitted_column` varchar(45) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
2. create procedure.
3. execute procedure.
4. check table my_splits.
* you may update it with your ID specific requirements, I suppose it'd be easy or may be you can do that using join+find in set query.
Happy Weekend!!
CREATE DEFINER=`root`@`localhost` PROCEDURE `split_string`()
BEGIN
DECLARE my_delimiter CHAR(1);
DECLARE split_string varchar(255);
DECLARE done INT;
DECLARE occurance INT;
DECLARE i INT;
DECLARE ins_query VARCHAR(500);
DECLARE tmp_query VARCHAR(500);
DECLARE splitter_cur CURSOR FOR
SELECT cat from test.tmp;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
OPEN splitter_cur;
splitter_loop:LOOP
FETCH splitter_cur INTO split_string;
SET occurance=length(split_string)-length(replace(split_string,';',''))+1;
SET my_delimiter=';';
IF done=1 THEN
LEAVE splitter_loop;
END IF;
# select occurance;
IF occurance > 0 then
#select occurance;
set i=1;
while i <= occurance do
# select concat("SUBSTRING_INDEX(SUBSTRING_INDEX( '",split_string ,"', '",my_delimiter,"', ",i, "),'",my_delimiter,"',-1);");
SET ins_query=concat("insert into test.my_splits(splitted_column) values(", concat("SUBSTRING_INDEX(SUBSTRING_INDEX( '",split_string ,"', '",my_delimiter,"', ",i, "),'",my_delimiter,"',-1));"));
set @ins_query=ins_query;
PREPARE ins_query from @ins_query;
EXECUTE ins_query;
set i=i+1;
end while;
ELSE
set ins_query=concat("insert into test.my_splits(splitted_column) values(",split_string,"');");
set @ins_query=ins_query;
PREPARE ins_query from @ins_query;
EXECUTE ins_query;
END IF;
set occurance=0;
END LOOP;
CLOSE splitter_cur;
END
I am not good at MySQL but I am sure you fix this query if it fails...
select distinct id, trim(kw) as keyword from (
select id, SUBSTRING_INDEX(keywords, ';', 1) as kw from KWTable
union
select id, SUBSTRING_INDEX(SUBSTRING(keywords, ';', 2),';',-1) from KWTable
union
select id, SUBSTRING_INDEX(SUBSTRING(keywords, ';', 3),';',-1) from KWTable
union
select id, SUBSTRING_INDEX(SUBSTRING(keywords, ';', 4),';',-1) from KWTable
union
select id, SUBSTRING_INDEX(SUBSTRING(keywords, ';', 5),';',-1) from KWTable
union
select id, SUBSTRING_INDEX(SUBSTRING(keywords, ';', 6),';',-1) from KWTable
union
select id, SUBSTRING_INDEX(keywords, ';', -1) from KWTable
) where kw is not null
note that above solution is based on assumption that max keyword in keywords is 7...
ASKER
Thank you to both,
theGhost_k8 you soluction is ok, but i need the procedure insert id, ¿Why?
why some words repeats many times, if i used join+find i dont know exactly id for each word. This for a keywords table asociate to a news table and some news use same word and need asosiate news ID with keyword ID.
Thanks again,
theGhost_k8 you soluction is ok, but i need the procedure insert id, ¿Why?
why some words repeats many times, if i used join+find i dont know exactly id for each word. This for a keywords table asociate to a news table and some news use same word and need asosiate news ID with keyword ID.
Thanks again,
Hi following query fixes id issues... Change table names accordingly.
mysql> update tmp,my_splits set my_splits.id=tmp.id where find_in_set(splitted_colum n,replace( cat,';',', '));
You may add ID column to your my_splits table and fire following update query.
I'm little lazy to update the SP now, I hope it works for you!
mysql> update tmp,my_splits set my_splits.id=tmp.id where find_in_set(splitted_colum
You may add ID column to your my_splits table and fire following update query.
I'm little lazy to update the SP now, I hope it works for you!
ASKER
if you see keyword "A Casa é Sua" repeat 116 times. all with diferents ID.
id keywords
538 A Casa é Sua
653 A casa é sua
676 A Casa é Sua
894 Sabrina Sato ; A casa é sua
1314 Gustavo Baena ; A Casa é Sua
1411 A Casa é Sua
1433 A casa é sua
.........
with update you
"query mysql> update tmp,my_splits set my_splits.id=tmp.id where find_in_set(splitted_colum n,replace( cat,';',', '));"
can you see the id is same for all keyword named "A Casa é Sua" when in original tables have 116 diferents id's.
ID splitted_column
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
id keywords
538 A Casa é Sua
653 A casa é sua
676 A Casa é Sua
894 Sabrina Sato ; A casa é sua
1314 Gustavo Baena ; A Casa é Sua
1411 A Casa é Sua
1433 A casa é sua
.........
with update you
"query mysql> update tmp,my_splits set my_splits.id=tmp.id where find_in_set(splitted_colum
can you see the id is same for all keyword named "A Casa é Sua" when in original tables have 116 diferents id's.
ID splitted_column
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
538 A Casa é Sua
Right, I agree for a repeated value even id will repeat... You still can modify the SP; can't you?
It took minutes.
Check below code now:
Check below code now:
DELIMITER $$
DROP PROCEDURE IF EXISTS `split_string` $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `split_string`()
BEGIN
DECLARE my_delimiter CHAR(1);
DECLARE split_string varchar(255);
DECLARE done INT;
DECLARE occurance INT;
DECLARE i INT;
DECLARE split_id INT;
DECLARE ins_query VARCHAR(500);
DECLARE splitter_cur CURSOR FOR
SELECT id,cat from test.tmp;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
OPEN splitter_cur;
splitter_loop:LOOP
FETCH splitter_cur INTO split_id,split_string;
SET occurance=length(split_string)-length(replace(split_string,';',''))+1;
SET my_delimiter=';';
IF done=1 THEN
LEAVE splitter_loop;
END IF;
# select occurance;
IF occurance > 0 then
#select occurance;
set i=1;
while i <= occurance do
# select concat("SUBSTRING_INDEX(SUBSTRING_INDEX( '",split_string ,"', '",my_delimiter,"', ",i, "),'",my_delimiter,"',-1);");
SET ins_query=concat("insert into test.my_splits(splitted_column,id) values(", concat("SUBSTRING_INDEX(SUBSTRING_INDEX( '",split_string ,"', '",my_delimiter,"', ",i, "),'",my_delimiter,"',-1),",split_id,");"));
select ins_query;
set @ins_query=ins_query;
PREPARE ins_query from @ins_query;
EXECUTE ins_query;
set i=i+1;
end while;
ELSE
set ins_query=concat("insert into test.my_splits(splitted_column) values(",split_string,"');");
set @ins_query=ins_query;
PREPARE ins_query from @ins_query;
EXECUTE ins_query;
END IF;
set occurance=0;
END LOOP;
CLOSE splitter_cur;
END $$
DELIMITER ;
You may comment-out Line - 35: select ins_query;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
mmmm..... i see that script dont work correctly, i attach table Keyword_temp with ID and Keywords.
The procedure work same that last soluctioón, make you a test.
Thanks for you time.
Razz
keywords-temp.zip
The procedure work same that last soluctioón, make you a test.
Thanks for you time.
Razz
keywords-temp.zip
I altered keywords_temp.txt for table / column names and used as follows:
1. mysql -uroot -pkedar test < keywords_temp.txt
2. call split_string();
3. select * from my_splits;
Attachments:
- My keywords_temp.txt
- Output exported in excel after executing step 3.
What is missing?
keywords-temp.txt
my-splits.xls
1. mysql -uroot -pkedar test < keywords_temp.txt
2. call split_string();
3. select * from my_splits;
Attachments:
- My keywords_temp.txt
- Output exported in excel after executing step 3.
What is missing?
keywords-temp.txt
my-splits.xls
ASKER
well, im back, work trip.
Im my server dont work, i try mount a mysql server and try again.
Thanks for you help.
Im my server dont work, i try mount a mysql server and try again.
Thanks for you help.
ASKER
well, im back, work trip.
Im my server dont work, i try mount a mysql server and try again.
Thanks for you help.
Im my server dont work, i try mount a mysql server and try again.
Thanks for you help.
above mention link add the one more parameter id and insert the same in temeporaty table ....
this link may help out