首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

字符串检索的有关问题

2013-10-16 
字符串检索的问题这是 http://bbs.csdn.net/topics/390530288问题的 一个变种表IDIndexArr11,2,3,4,5255,6

字符串检索的问题
这是 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变量中出现了


热点排行