您可以使用RegEx将逗号分隔的字符串解析为MySQL中的临时表吗?
'1|2|5|6' into temp table with 4 rows.
答案 0 :(得分:33)
MySQL没有拆分字符串功能,所以你必须做解决方法。使用上面答案页面中列出的方法之一拆分后,您可以对数据执行任何操作。
你可以遍历那个自定义函数并在它返回空时中断,你必须播放并学习一些语法(或者至少我会)但是mysql中FOR循环的语法在这里: http://www.roseindia.net/sql/mysql-example/for.shtml
你可以迭代它,增加下面函数中的位置:
CREATE FUNCTION SPLIT_STR(
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '');
(信用:https://blog.fedecarg.com/2009/02/22/mysql-split-string-function/)
如果未找到匹配项,则返回'',如果未找到匹配项,则中断循环。这将允许您只对解析字符串进行mysql解析,并将插入查询运行到临时表中。但是为什么不仅仅使用像php那样的脚本语言进行那种工作呢? :(
循环语法代码:
DELIMITER $$
CREATE PROCEDURE ABC(fullstr)
BEGIN
DECLARE a INT Default 0 ;
DECLARE str VARCHAR(255);
simple_loop: LOOP
SET a=a+1;
SET str=SPLIT_STR(fullstr,"|",a);
IF str='' THEN
LEAVE simple_loop;
END IF;
#Do Inserts into temp table here with str going into the row
insert into my_temp_table values (str);
END LOOP simple_loop;
END $$
答案 1 :(得分:3)
我已经这样做了,因为当你没有表值时等等:
select *
from(
select c, SUBSTRING_INDEX(SUBSTRING_INDEX('1|2|5|6', '|', c+1), '|', -1) as name
from(
SELECT (TWO_1.SeqValue + TWO_2.SeqValue + TWO_4.SeqValue + TWO_8.SeqValue + TWO_16.SeqValue + TWO_32.SeqValue) c
FROM (
SELECT 0 SeqValue UNION ALL SELECT 1 SeqValue) TWO_1
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 2 SeqValue) TWO_2
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 4 SeqValue) TWO_4
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 8 SeqValue) TWO_8
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 16 SeqValue) TWO_16
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 32 SeqValue) TWO_32
) as b
WHERE c <= (CHAR_LENGTH('1|2|5|6') - CHAR_LENGTH(REPLACE('1|2|5|6', '|', '')))
) as a;
可能不是最好的答案,但没有功能和程序的帮助,没有额外的表格等。
答案 2 :(得分:2)
您可以在MySQL中使用正则表达式来指定复杂搜索的模式,您无法解析字符串。
但是您可以在REPLACE和CONCATENATE的帮助下构建INSERT查询以将数据保存到临时表。
答案 3 :(得分:2)
DELIMITER $$
CREATE PROCEDURE SPLIT_VALUE_STRING()
BEGIN
SET @String = '1,22,333,444,5555,66666,777777';
SET @Occurrences = LENGTH(@String) - LENGTH(REPLACE(@String, ',', ''));
myloop: WHILE (@Occurrences > 0)
DO
SET @myValue = SUBSTRING_INDEX(@String, ',', 1);
IF (@myValue != '') THEN
/* my code... */
ELSE
LEAVE myloop;
END IF;
SET @Occurrences = LENGTH(@String) - LENGTH(REPLACE(@String, ',', ''));
IF (@occurrences = 0) THEN
LEAVE myloop;
END IF;
SET @String = SUBSTRING(@String,LENGTH(SUBSTRING_INDEX(@String, ',', 1))+2);
END WHILE;
END $$
答案 4 :(得分:2)
我找到了很好的解决方案
https://forums.mysql.com/read.php?10,635524,635529
感谢Peter Brawley
技巧:将csv字符串上的Group_Concat()结果按到一个 插入...值...字符串:
drop table if exists t;
create table t( txt text );
insert into t values('1,2,3,4,5,6,7,8,9');
drop temporary table if exists temp;
create temporary table temp( val char(255) );
set @sql = concat("insert into temp (val) values ('", replace(( select group_concat(distinct txt) as data from t), ",", "'),('"),"');");
prepare stmt1 from @sql;
execute stmt1;
select distinct(val) from temp;
+------+
| val |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+------+
此外,如果您只想将某些表连接到id列表,则可以使用LIKE运算符。 有我的解决方案,我从博客帖子网址获取id列表,将它们转换为逗号分隔列表开始并用逗号结束,然后通过id列表与LIKE运算符加入相关产品。
SELECT b2.id blog_id, b2.id_list, p.id
FROM (
SELECT b.id,b.text,
CONCAT(
",",
REPLACE(
EXTRACTVALUE(b.text,'//a/@id')
, " ", ","
)
,","
) AS id_list
FROM blog b
) b2
LEFT JOIN production p ON b2.id_list LIKE CONCAT('%,',p.id,',%')
HAVING b2.id_list != ''
答案 5 :(得分:1)
select distinct
SUBSTRING_INDEX(SUBSTRING_INDEX('1,2,3,4', ',', numbers.n), ',', -1) name
from
(select @rownum := @rownum + 1 as n
from YourTable
cross join (select @rownum := 0) r
) numbers
order by
n
答案 6 :(得分:0)
如果您尝试拆分的文本包含多字节字符,则此方法会因为LENGTH计算错误而中断。对于这种情况,使用CHAR_LENGTH而不是LENGTH的以下版本可以使用:
CREATE DEFINER=`root`@`localhost` FUNCTION `strSplit`(
`src` MEDIUMTEXT CHARACTER SET utf8,
`delim` VARCHAR(12),
`pos` INTEGER
)
RETURNS mediumtext
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE output MEDIUMTEXT CHARACTER SET utf8;
SET output = REPLACE(SUBSTRING(SUBSTRING_INDEX(src, delim, pos) ,
CHAR_LENGTH(SUBSTRING_INDEX(src, delim, pos - 1)) + 1) , delim , '');
IF output = '' THEN SET output = null; END IF;
RETURN output;
END
参考:http://www.shakedos.com/2011/Nov/23/mysql-split-string-function-fix-split_str.html
答案 7 :(得分:0)
因为我真的喜欢复活旧问题:
CREATE PROCEDURE `SPLIT_LIST_STR`(IN `INISTR` TEXT CHARSET utf8mb4, IN `ENDSTR` TEXT CHARSET utf8mb4, IN `INPUTSTR` TEXT CHARSET utf8mb4, IN `SEPARATR` TEXT CHARSET utf8mb4)
BEGIN
SET @I = 1;
SET @SEP = SEPARATR;
SET @INI = INISTR;
SET @END = ENDSTR;
SET @VARSTR = REPLACE(REPLACE(INPUTSTR, @INI, ''), @END, '');
SET @N = FORMAT((LENGTH(@VARSTR)-LENGTH(REPLACE(@VARSTR, @SEP, '')))/LENGTH(@SEP), 0)+1;
CREATE TEMPORARY TABLE IF NOT EXISTS temp_table(P1 TEXT NULL);
label1: LOOP
SET @TEMP = SUBSTRING_INDEX(@VARSTR, @SEP, 1);
insert into temp_table (`P1`) SELECT @TEMP;
SET @I = @I + 1;
SET @VARSTR = REPLACE(@VARSTR, CONCAT(@TEMP, @SEP), '');
IF @N >= @I THEN
ITERATE label1;
END IF;
LEAVE label1;
END LOOP label1;
SELECT * FROM temp_table;
END
哪个产生:
P1
1
2
3
4
使用CALL SPLIT_LIST_STR('("', '")', '("1", "2", "3", "4")', '", "');
我可能会在以后弹出代码更多!干杯!