原文:在论坛中出现的比较难的sql问题:25(字符串拆分3)
最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。
所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。
1、求教超难的字符串去重问题?
http://bbs.csdn.net/topics/390719864
现在小弟有如此一数据表
结构如下:
select 1 as tname,'01:0102;02:0102;03:0102;04:0102,0101;05:0102'as tstr into tb1
insert into tb1 select 2,'01:0101,0102'
insert into tb1 select 3,'01:0102;02:0102;03:0102;04:0102;05:0102'
insert into tb1 select 4,'01:0102,0103'
insert into tb1 select 5,'0104'
insert into tb1 select 6,'01:0102;02:0102;03:0102;04:0102;05:0102'
insert into tb1 select 7,'01:0102;02:0102;03:0102;04:0102,0101;05:0102'
上表数据代表的含义
tname 为序号,不用管
tstr 为编组内容
01:0101,0102 意思为01组,组员为编号0101和0102两人组成。
01:0102;02:0102 意思为编号0102的组员,即在01组,又在02组。
可见有很多重复。
现在查询想得到如下结果:即找出这几些编组到底有哪些组员:
0101,0102,0103,0104
求存储过程,不能创建自定义函数,谢谢
注意数据库版本为sqlserver 2k
我的方法:
-
--drop table tbl
-
-
create table tbl(tname int,tstr varchar(100))
-
-
insert into tbl
-
select 1 ,'01:0102;02:0102;03:0102;04:0102,0101;05:0102'
-
-
insert into tbl
-
select 2,'01:0101,0102'
-
-
insert into tbl
-
select 3,'01:0102;02:0102;03:0102;04:0102;05:0102'
-
-
insert into tbl
-
select 4,'01:0102,0103'
-
-
insert into tbl
-
select 5,'0104'
-
-
insert into tbl
-
select 6,'01:0102;02:0102;03:0102;04:0102;05:0102'
-
-
insert into tbl
-
select 7,'01:0102;02:0102;03:0102;04:0102,0101;05:0102'
-
go
-
declare @str varchar(1000)
-
-
set @str = ''
-
-
select @str = @str + ','+ [编组]
-
from
-
(
-
select --*,
-
distinct
-
case when vv like '%:%' then SUBSTRING(vv,charindex(':',vv)+1,len(vv))
-
else vv
-
end '编组'
-
from
-
(
-
select tname,
-
tstr,
-
v,
-
SUBSTRING(t.v, number ,CHARINDEX(',',t.v+',',number)-number) vv
-
from
-
(
-
select tname,
-
tstr,
-
SUBSTRING(t.tstr, number ,CHARINDEX(';',t.tstr+';',number)-number) v
-
from tbl t,master..spt_values s
-
where s.number >=1
-
and s.type = 'P'
-
and SUBSTRING(';'+t.tstr,s.number,1) = ';'
-
)t,master..spt_values s
-
where s.number >=1
-
and s.type = 'P'
-
and SUBSTRING(','+t.v,s.number,1) = ','
-
)t
-
)t
-
order by [编组]
-
-
select stuff(@str,1,1,'') as [编组]
-
/*
-
编组
-
0101,0102,0103,0104
-
*/