MySQL没有Split函数,但可以通过写UDF来实现,上网查了很多,但都有些不完美之处,比如:如果遇到不确定有多少个分隔符的情况下,想要切分后取指定位置的字符,会有可能取错或取不出来。
因此重新写了一个支持自动计算可切分的数量,并在超过有效切分数量范围时返回空值,这样即能保证不会取错,又支持特定应用,比如我需要将一个不定长的字段(如字段可能的值有:A1/A2/A3 , A1/A2, A1/A2/A3/A4),指定取分割后的第4个值,想实现的效果是当第4个值时取对应的值,如果无值时返回空值(null)。
函数说明:
函数功能: Split功能函数
功能说明: 支持分隔符有多个字符.同时如果输入的位置超过可分割数量时返回空值.
使用方法: udf_split(f_string,f_delimiter,f_order)
示例: select udf_split('ABC||DEF||GH||I', '||', 2);
特殊说明:
1、当分隔符后或前无其他字符,返回的是空串,而不是空值null。
2、当输入的位置比实际可切分的数量大时,则返回空值null。
如执行以下语句:
select
udf_split(',a,b,',',',1) as split1,
udf_split(',a,b,',',',2) as split2,
udf_split(',a,b,',',',3) as split3,
udf_split(',a,b,',',',4) as split4,
udf_split(',a,b,',',',5) as split5;
得到以下结果:
![](https://img.haomeiwen.com/i15644869/6ad1d048e4ef5186.png)
代码实现:
DELIMITER $$
DROP function IF EXISTS `udf_split` $$
CREATE FUNCTION `udf_split`
( f_string varchar(8000), f_delimiter varchar(50), f_order int)
RETURNS varchar(500) CHARSET utf8
BEGIN
-- 声明变量
declare result varchar(500) default '';
declare totalcnt INT;
set result = '';
-- 计算有效数量
set totalcnt = ((length(f_delimiter) + (length(f_string) - length(replace(f_string,f_delimiter,'')))) / length(f_delimiter));
-- 判断输入的位置是否超过有效数量
if f_order > 0 and f_order <= totalcnt then
set result = reverse(substring_index(reverse(substring_index(f_string,f_delimiter,f_order)),f_delimiter,1));
else
set result = null;
end if;
return result;
END$$
DELIMITER ;
测试结果:
select txt,
udf_split(txt,',',1) as split1,
udf_split(txt,',',2) as split2,
udf_split(txt,',',3) as split3,
udf_split(txt,',',4) as split4,
udf_split(txt,',',5) as split5,
udf_split(txt,'||',1) as split1a,
udf_split(txt,'||',2) as split2a,
udf_split(txt,'||',3) as split3a,
udf_split(txt,'||',4) as split4a,
udf_split(txt,'||',5) as split5a
from (
select 'a,b,c,d' as txt union all
select 'a,b,c' as txt union all
select 'a,b' as txt union all
select 'a' as txt union all
select 'a||b||c||d' as txt union all
select 'a||b||c||' as txt union all
select '测||试||程||序' as txt
) a;
![](https://img.haomeiwen.com/i15644869/ee3035a2bd2d104a.png)
网友评论