我想拆分各列的每个名称
create table split_test(value integer,Allnames varchar(40))
insert into split_test values(1,'Vinoth,Kumar,Raja,Manoj,Jamal,Bala');
select * from split_test;
Value Allnames
-------------------
1 Vinoth,Kumar,Raja,Manoj,Jamal,Bala
预期输出
values N1 N2 N3 N4 N5 N6 N7.......N20
1 Vinoth Kumar Raja Manoj Jamal Bala
答案 0 :(得分:0)
使用这个例子你可以得到一个想法。
declare @str varchar(max)
set @str = 'Hello world'
declare @separator varchar(max)
set @separator = ' '
declare @Splited table(id int identity(1,1), item varchar(max))
set @str = REPLACE(@str,@separator,'''),(''')
set @str = 'select * from (values('''+@str+''')) as V(A)'
insert into @Splited
exec(@str)
select * from @Splited
答案 1 :(得分:0)
这是一个使用递归CTE将名称拆分为行,然后将行转移到列中的sql语句。 SqlFiddle
with names as
(select
value,
1 as name_id,
substring(Allnames,1,charindex(',',Allnames+',', 0)-1) as name,
substring(Allnames,charindex(',',Allnames, 0)+1, 40) as left_names
from split_test
union all
select
value,
name_id +1,
case when charindex(',',left_names, 0)> 0 then
substring(left_names,1,charindex(',',left_names, 0)-1)
else left_names end as name,
case when charindex(',',left_names, 0)> 0 then
substring(left_names,charindex(',',left_names, 0)+1, 40)
else '' end as left_names
from names
where ltrim(left_names)<>'')
select value,
[1],[2],[3],[4],[5],[6],[7],[8],[9]
from (select value,name_id,name from names) as t1
PIVOT (MAX(name) FOR name_id IN ( [1],[2],[3],[4],[5],[6],[7],[8],[9] ) ) AS t2
<强>更新强>
@KM.'s answer 可能是在没有递归CTE表的情况下将数据拆分为行的更好方法。它应该比这个更有效。所以我遵循这个例子并简化了空值过程逻辑的一部分。结果如下:
第1步:
创建一个表格,其中包含从1到数字的所有数字,而不是Allnames
列的最大长度。
CREATE TABLE Numbers( Number int not null primary key);
with n as
(select 1 as num
union all
select num +1
from n
where num<100)
insert into numbers
select num from n;
第2步:
将split_test表的数据与数字表连接起来,我们可以从,
开始获取所有部分。
然后在每行2 ,
之间取第一部分。如果存在空值,请使用union添加它们。
select value ,
ltrim(rtrim(substring(allnames,number+1,charindex(',',substring(allnames,number,40),2)-2))) as name
from
(select value, ','+allnames+',' as allnames
from split_test) as t1
left join numbers
on number<= len(allnames)
where substring(allnames,number,1)=','
and substring(allnames,number,40)<>','
union
select value, Allnames
from split_test
where Allnames is null
第3步:将行名称从行转移到列,就像我上面的第一次尝试一样,这里省略了。 SQLFiddle