34,588
社区成员
发帖
与我相关
我的任务
分享
--sql 2000
create table tb(ar varchar(20))
insert into tb
select 'a,b,c,' union all
select 'aa,bb,' union all
select 'cc,'
go
declare @sql varchar(8000)
select identity(int,1,1) as px,ar into #tb
from tb
select distinct a.px,substring(left(a.ar,len(a.ar)-1),b.number,charindex(',',a.ar,b.number) - b.number) ar,id = identity(int,1,1)
into #t1
from #tb a,master..spt_values b
where b.[type] = 'p' and b.number between 1 and len(a.ar)
and substring(',' + stuff(a.ar,len(a.ar),1,''),b.number,1) = ','
select px,ar,rn = (select count(*) from #t1 where px = t.px and id <= t.id)
into #tp
from #t1 t
set @sql = 'select px'
select @sql = @sql + ',max(case rn when ' + ltrim(rn) + ' then ar else '''' end)[strid' + ltrim(rn) + ']'
from(select distinct rn from #tp)t
select @sql = @sql + ' from #tp group by px'
exec(@sql)
drop table tb,#tb,#tp,#t1
/*
px strid1 strid2 strid3
----------- -------------------- -------------------- --------------------
1 a b c
2 aa bb
3 cc
(3 行受影响)
--麻烦点吧!
create table tb(ar varchar(20))
insert into tb
select 'a,b,c,' union all
select 'aa,bb,' union all
select 'cc,'
go
declare @sql varchar(max)
select identity(int,1,1) as px,ar into #tb
from tb
select *,rn = row_number() over (partition by px order by getdate())
into #tp
from(
select distinct a.px,substring(left(a.ar,len(a.ar)-1),b.number,charindex(',',a.ar,b.number) - b.number) ar
from #tb a,master..spt_values b
where b.[type] = 'p' and b.number between 1 and len(a.ar)
and substring(',' + stuff(a.ar,len(a.ar),1,''),b.number,1) = ',')t
set @sql = 'select px'
select @sql = @sql + ',max(case rn when ' + ltrim(rn) + ' then ar else '''' end)[strid' + ltrim(rn) + ']'
from(select distinct rn from #tp)t
select @sql = @sql + ' from #tp group by px'
exec(@sql)
drop table tb,#tb,#tp
/*
px strid1 strid2 strid3
----------- -------------------- -------------------- --------------------
1 a b c
2 aa bb
3 cc
(3 行受影响)
----------------------------------------------------------------
-- Author :fredrickhu(小F,向高手学习)
-- Date :2011-04-01 14:18:26
-- Verstion:
-- Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86)
-- Jul 9 2008 14:43:34
-- Copyright (c) 1988-2008 Microsoft Corporation
-- Enterprise Edition on Windows NT 5.2 <X86> (Build 3790: Service Pack 2)
--
----------------------------------------------------------------
--> 测试数据:[tb]
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([strid] varchar(17))
insert [tb]
select '3304,330301,3305' union all
select '33,3305' union all
select '330302'
--------------开始查询--------------------------
select
reverse(PARSENAME(replace(reverse(strid),',','.'),1)) as strid1,
reverse(PARSENAME(replace(reverse(strid),',','.'),2)) as strid2,
reverse(PARSENAME(replace(reverse(strid),',','.'),3)) as strid3
from
tb
----------------结果----------------------------
/* strid1 strid2 strid3
-------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------
3304 330301 3305
33 3305 NULL
330302 NULL NULL
(3 行受影响)
*/
--->测试数据
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([strid] varchar(17))
insert [tb]
select '3304,330301,3305,' union all
select '33,3305,' union all
select '330302,'
go
/**
--功能:分割字符串,取第@i个值
--Author:josy(百年树人)
--参数@s:字符串
--参数@i:取第几个值
--参数@sign:分隔符
**/
create function [dbo].[f_col](@s varchar(100),@i int,@sign varchar(10))
returns varchar(200)
as
begin
declare @t table(id int identity(1,1),col varchar(100));
declare @cnt int,@rel varchar(200)
--set @s=@s+@sign --如果结尾没有分隔符,则加上这一句
set @cnt=datalength(@s)-datalength(replace(@s,@sign,''))
while @cnt>0
begin
insert @t(col) select left(@s,charindex(@sign,@s)-1)
set @cnt=@cnt-1
set @s=stuff(@s,1,charindex(@sign,@s),'')
end
select @rel=col from @t where id=@i
return @rel
end
go
--->查询
select
dbo.f_col(strid,1,',') as strid1,
dbo.f_col(strid,2,',') as strid2,
dbo.f_col(strid,3,',') as strid3
from tb
/**
strid1 strid2 strid3
---------- ---------- ----------
3304 330301 3305
33 3305 NULL
330302 NULL NULL
(3 行受影响)
**/