最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。
所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。
字符串检索问题:http://bbs.csdn.net/topics/390608926
这是 http://bbs.csdn.net/topics/390530288 问题的 一个变种
表
ID IndexArr
1 1,2,3,4,5
2 55,6,99,87,1000
3 7,567567,567,43,123
IndexArr 是","分割的数字
现在有字符串 ‘2,34,45,345,867,4,984‘
现在要检索的是 IndexArr 中每一个数字都在 字符串中出现过的 结果集。
我的解法:
- --1.函数
- if exists(select * from sys.objects where name = ‘f_splitSTR‘ and type = ‘tf‘)
- drop function dbo.f_splitSTR
- go
-
- create function dbo.f_splitSTR
- (
- @s varchar(8000), --要分拆的字符串
- @split varchar(10) --分隔字符
- )
- returns @re table( --要返回的临时表
- col varchar(1000) --临时表中的列
- )
- as
- begin
- declare @len int
-
- set @len = LEN(@split) --分隔符不一定就是一个字符,可能是2个字符
-
- while CHARINDEX(@split,@s) >0
- begin
- insert into @re
- values(left(@s,charindex(@split,@s) - 1))
-
- set @s = STUFF(@s,1,charindex(@split,@s) - 1 + @len ,‘‘) --覆盖:字符串以及分隔符
- end
-
- insert into @re values(@s)
-
- return --返回临时表
- end
- go
-
-
-
- --> 测试数据:[tb]
- if object_id(‘[tb]‘) is not null
- drop table [tb]
- go
-
- create table [tb]([ID] int,[IndexArr] varchar(19))
- insert [tb]
- select 1,‘1,2,3,4,5‘ union all
- select 2,‘55,6,99,87,1000‘ union all
- select 3,‘7,567567,567,43,123‘ union ALL
- SELECT 4,‘2,34,45‘
-
-
-
- --------------开始查询--------------------------
- DECLARE @s VARCHAR(1000)
-
- SET @s= ‘2,34,45,345,867,4,984‘
-
-
- ;with t
- as
- (
- select t.ID,
- t.IndexArr,
- f.col,
-
- --把IndexArr按照分隔符,拆分成了多少个字符串
- COUNT(*) over(PARTITION by IndexArr) as split_str_count
- from tb t
- cross apply dbo.f_splitSTR(t.IndexArr,‘,‘) f
- )
-
- select t.ID,
- t.IndexArr
- from t
- where charindex(col, ‘,‘+@s+‘,‘) > 0
- group by t.ID,
- t.IndexArr,
- t.split_str_count
- having COUNT(*) = t.split_str_count --比如2,34,45分拆为3个字符串,
- --那么在经过where条件过滤后,记录数也必须是3
- --这样说明了indexarr中的字符串都在@s变量中出现了
-
在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题)
原文:https://www.cnblogs.com/lonelyxmas/p/12020071.html