字符串检索的问题
这是 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 中每一个数字都在 字符串中出现过的 结果集
[解决办法]
写一个笨方法:
----------------------------
-- Author :fredrickhu(小F,向高手学习)
-- Date :2013-10-08 16:36:59
-- Verstion:
-- Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
--Feb 10 2012 19:39:15
--Copyright (c) Microsoft Corporation
--Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
--
----------------------------
--> 测试数据:[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'
set @s = 'select name='''+replace(@s,',',''''+' union all select ''')+''''
set @s='select name into #t from ('+@s+') a
;with f as
(
Select
a.id,IndexArr=substring(a.IndexArr,b.number,charindex('','',a.IndexArr+'','',b.number)-b.number)
from
Tb a join master..spt_values b
ON B.type=''p'' AND B.number BETWEEN 1 AND LEN(A.IndexArr)
where
substring('',''+a.IndexArr,b.number,1)='',''
)
, f2 as
(
select id,count(1) as num from f t where exists(select 1 from #t where name=t.IndexArr) group by id
)
select a.* from tb a ,f2 b where len(a.IndexArr)-len(replace(a.IndexArr,'','',''''))+1=b.num
drop table #t'
EXEC(@s)
----------------结果----------------------------
/* ID IndexArr
----------- -------------------
4 2,34,45
(1 行受影响)
*/
--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变量中出现了