最近在工作中有这样一个需求,匹配String str1 = 'a|b|c'和String str2 = 'e|a|c|d',以'|'为分隔符分割,分割后str1 = {a,b,c} str2={e,a,c,d},若str1和str2分割后有重复的项则返回为1,否则返回0

很多熟悉sql的人都知道,匹配字符串有个like函数,但是like函数匹配的字段必须是完全相同的

例如:select 'a|b|c' like '%a|b%'    是如果第一个字符串含有第二个字符串的话返回为1,此语句的返回值为1

但是    select 'a|b|c' like '%a|c%' 返回为0,也就是第一个字符串没有完全匹配第二个字符串

如果我们想要以'|'为分隔符,如果第一个字符串与第二个字符串有相同的部分,就返回为1,反之返回为0的话单单用一条like语句就无法实现了,这个时候的实现思想可以是把第二个字符串用'|'分隔开之后,意义去分隔开的数据,然后与第一个字符串进行like查询,也就是将

select 'a|b|c' like '%a|c%'

拆分为

select 'a|b|c' like '%a%' 和select 'a|b|c' like '%c%'

拆分后查询若有一个为1,就代表有相同的选项,就返回为1;拆分后的查询都为0,就代表无匹配的项,就返回为1

说到这里,我们就很自然而然的想到了,这个思想可以用函数实现,函数如下:

(这个函数是同事写出来的,不知是否有参考网上代码,因此也不知源码地址,如有人知道,可以在评论里指出)

set @tmp = a;
set @result = 0;
set @token = '';
set @ind = 0;


		while (@tmp <> '') DO
			-- |的索引
			set @ind =  position('|' in @tmp);
			
			if( @ind <= 0) THEN
				set @token = @tmp;
				set @result =  @token REGEXP b;
				set @tmp = '';
			ELSE 
				set @token = left(@tmp,@ind - 1);
				set @result =  @token REGEXP b;
				
				if(@result > 0) THEN
					set @tmp = '';
				ELSE
					-- 修改原始字符串
				set @tmp = right(@tmp,LENGTH(@tmp) - @ind);
				END IF;
		
			end IF;
		END WHILE;			
return @result;
end






现在利用上面的函数再执行一下

select getLike('a|b|c','a|b')




返回结果为1


起初这个函数是能够正常执行的,但是随着运用的次数增多,函数显示显示出了这个函数的隐藏bug,就是不能匹配中文,select getLike('技术|运营|产品','%技术|运营%'),执行这句代码数据库就会卡死,原因是getLike函数中的REGEXP不支持中文
因此,上面的函数改成了下面这样

<pre name="code" class="sql">BEGIN
set @tmp = a;
set @result = 0;
set @token = '';
set @ind = 0;


		while (@tmp <> '') DO
			-- |的索引
			set @ind =  position('|' in @tmp);
			
			if( @ind <= 0) THEN
				set @token = @tmp;
				set @result = b like concat('%',@token,'%');
				set @tmp = '';
			ELSE
				set @token = SUBSTRING(@tmp FROM 1 for @ind - 1);
				set @result =  b like concat('%',@token,'%');
				
				if(@result > 0) THEN
					set @tmp = '';
				ELSE
					-- 修改原始字符串
				set @tmp = SUBSTRING(@tmp FROM @ind + 1);
				END IF;
		
			end IF;
		END WHILE;			
return @result;
end





现在再试一下

select getLikeNew('技术|运营|产品','技术|运营')






返回就是1了



如果有人有更好的方法可以写下来一起分享哦~哪里写的不完全正确也欢迎指出~~