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

关于字符串的检索有关问题(续一)

2012-03-30 
关于字符串的检索问题(续一)现有表AIDintString-----------117,14,15213,11,163Null412,22,10表BIDName---

关于字符串的检索问题(续一)
现有表A
ID   intString
-----------
1     17,14,15
2     13,11,16
3     Null
4     12,22,10

表B
ID   Name
---------
10   abcd
11   aaaa
12   abcc
13   bbbb
14   abab
15   bcbc
16   cccc
17   acac
18   cdcd

需要得到下列结果:
ID   charString
----------------
1   abab,bcbc,acac
2   aaaa,bbbb,cccc
3   Null
4   abcd,abcc

即找出表A中intString字段中用逗号分隔的数字与表B中对应的Name
如果没有则忽略,并将检索出来的字符串中的Name按ID排序.

前两天在下面帖子里问过了
http://community.csdn.net/Expert/topic/5433/5433049.xml?temp=.1254999

我现在有个想法,能不能不用建函数和临时表来实现呢???

因为函数也涉及到表数据,感觉不是很好

[解决办法]
--减少至2个临时表,不能再少了。。。
--建立测试数据
CREATE TABLE tb_a(ID INT,intString VARCHAR(50))
INSERT tb_a
SELECT 1, '17,14,15 ' UNION ALL
SELECT 2, '13,11,16 ' UNION ALL
SELECT 3,NULL UNION ALL
SELECT 4, '12,22,10 ' UNION ALL
SELECT 5,NULL
GO

create table tb_b(id int,name varchar(40))
insert into tb_b select 10, 'abcd '
insert into tb_b select 11, 'aaaa '
insert into tb_b select 12, 'abcc '
insert into tb_b select 13, 'bbbb '
insert into tb_b select 14, 'abab '
insert into tb_b select 15, 'bcbc '
insert into tb_b select 16, 'cccc '
insert into tb_b select 17, 'acac '
insert into tb_b select 18, 'cdcd '
go

--生成临时表
SELECT TOP 8000 id = IDENTITY(int, 1, 1) INTO temp_1 FROM syscolumns a, syscolumns b

--分拆处理
SELECT a.ID,a.intString,b.name
INTO temp_2
FROM
(
SELECT A.id, 'intString '=SUBSTRING(A.intString, B.id, CHARINDEX( ', ', A.intString + ', ', B.id) - B.id)
FROM tb_a A, temp_1 B
WHERE SUBSTRING( ', ' + A.intString, B.id, 1) = ', '
) a, tb_b b
WHERE a.intString=b.ID
UNION
SELECT ID,0,NULL FROM tb_a
WHERE intString IS NULL
ORDER BY a.ID,a.intString

SELECT * FROM temp_2
GO

--写一个聚合函数:
create function dbo.fn_Merge(@F1 int)
returns varchar(8000)
as
begin
declare @r varchar(8000)
set @r= ' '
select @r=@r+ ', '+name from temp_2 where ID=@F1
return stuff(@r,1,1, ' ')
end
go

-- 调用函数
select ID, dbo.fn_Merge(ID) as name
from temp_2
group by ID
go

--删除测试
DROP TABLE tb_a
DROP TABLE tb_b
DROP TABLE temp_1
DROP TABLE temp_2
DROP FUNCTION fn_Merge

/*
IDintStringname
-------------------------------
114abab
115bcbc
117acac
211aaaa
213bbbb
216cccc
30NULL
410abcd
412abcc
50NULL

IDname
------------------------------
1abab,bcbc,acac
2aaaa,bbbb,cccc
3NULL
4abcd,abcc
5NULL
*/
[解决办法]
楼主是更新还是查询
如果是查询用函数吧
如果是更新是可以有临时表,2005不用函数和临时表都可以实现
[解决办法]
加了OrderBy就有問題,還是再加個表變量吧。

修改後,還是在一個函數中完成。

Create Table A
(IDInt,
intStringVarchar(100))
Insert A Select 1, '17,14,15 '
Union All Select 2, '13,11,16 '
Union All Select 3, Null
Union All Select 4, '12,22,10 '



Create Table B
(ID Int,
NameVarchar(100))
Insert B Select 10, 'abcd '
Union All Select 11, 'aaaa '
Union All Select 12, 'abcc '
Union All Select 13, 'bbbb '
Union All Select 14, 'abab '
Union All Select 15, 'bcbc '
Union All Select 16, 'cccc '
Union All Select 17, 'acac '
Union All Select 18, 'cdcd '
GO
Create Function F_UpdateName(@intString Varchar(100))
Returns Varchar(100)
As
Begin
Declare @S Varchar(100)

Declare @T Table (ID Int Identity(1, 1), Name Char(1))
Declare @T2 Table (ID Int , Name Varchar(100))
Insert @T Select Top 100 Null From Syscolumns A, Syscolumns B

Select @S = ' '

Insert
@T2
Select
B.ID,
B.Name
From
(
Select
Substring(@intString, ID, CharIndex( ', ', @intString + ', ', ID) - ID) As ID
From @T
Where Substring( ', ' + @intString, ID, 1) = ', '
) A
Inner Join
B
On A.ID = B.ID
Order By B.ID

Select @S = @S + ', ' + Name From @T2 Order By ID
Select @S = Stuff(@S, 1, 1, ' ')
Return @S
End
GO
Select ID, dbo.F_UpdateName(intString) As intString From A
GO
Drop Function F_UpdateName
Drop Table A, B
--Result
/*
IDintString
1abab,bcbc,acac
2aaaa,bbbb,cccc
3NULL
4abcd,abcc
*/

热点排行