2014-09-02 78 views
0

我想用這個例子,你可以得到一個想法單獨的列如何在sql server 2008R2中將單個單元分割爲多個列?

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

這是一個非常非常糟糕的設計。請規範你的桌子。 – 2014-09-02 04:49:22

+0

谷歌搜索:sql服務器將csv轉換爲行。 http://www.codeproject.com/Tips/732596/Converting-comma-separated-data-in-a-column-to-row – 2014-09-02 04:56:11

+0

可能的重複[如何使用SQL Server 2005將逗號分隔值展開爲單獨的行?](http://stackoverflow.com/questions/702968/how-do-i-expand-comma-separated-values-into-separate-rows-using-sql-server-2005) – 2014-09-02 04:56:59

回答

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('''[email protected]+''')) as V(A)' 

insert into @Splited 
exec(@str) 
select * from @Splited 
0

這裏是一個sql語句,它使用遞歸CTE將名字拆分成行,然後將行轉換爲列。 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 

UPDATE

@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 ,表格之間的第一部分。如果存在空值,請使用聯合添加它們。

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

+0

如果你環顧問題,你可以發現值的數量不是固定的(N1,N2 ...),所以你不能把它決定到6個級別。它可能或多或少... – 2014-09-02 14:21:38

相關問題