2013-12-11 61 views
3

我知道這個問題已經被問了好多次,但是找不到我需要的東西。在SQL Server 2008中用逗號分割函數

我有這個列「訂單」,其中包含以下格式的數據。 'xxx,yyy,zzzz'
現在,當我做我的select發言,我需要通過拆分這個

例如爲了填充3列

Select Name, 
    Surname, 
    FirstCommaColumn=xx.UpToFirstColumn 
    SecondCommaColumn=xx.FromFirstCommaToLastComma, 
    ThirdColumnFromSecondCommaOnwards=FromSecondCommaToEnd 
from myTable 
--thought of doing something like 
CROSS APPLY (SELECT TOP 1 * FROM dbo.SplitFunctionIDontHave(order,',')) AS xx 

有一些行沒有逗號,所以我必須返回空白。 我不介意如果我在一個函數或查詢本身中做的只是不知道如何做到這一點。

我該如何使用SQL Server 2008做到這一點? 這是選擇視圖的一部分,如果有差別

+0

在SQL服務器 – Jade

+0

玉無斯普利特()函數,我知道心不是我正在尋找一種能夠滿足我需要的功能或一些代碼來分割列的功能。 – user9969

+0

不要試圖將*多個*數據項存儲在一個列中會好得多。 –

回答

10

我已經改變函數的名稱,這樣就不會在什麼Split()功能確實重疊。

下面是代碼:

CREATE FUNCTION dbo.GetColumnValue(
@String varchar(8000), 
@Delimiter char(1), 
@Column int = 1 
) 
returns varchar(8000) 
as  
begin 

declare @idx int  
declare @slice varchar(8000)  

select @idx = 1  
    if len(@String)<1 or @String is null return null 

declare @ColCnt int 
    set @ColCnt = 1 

while (@idx != 0) 
begin  
    set @idx = charindex(@Delimiter,@String)  
    if @idx!=0 begin 
     if (@ColCnt = @Column) return left(@String,@idx - 1)   

     set @ColCnt = @ColCnt + 1 

    end 

    set @String = right(@String,len(@String) - @idx)  
    if len(@String) = 0 break 
end 
return @String 
end 

這裏是用法:

select dbo.GetColumnValue('Col1,Field2,VAlue3', ',', 3) 
+0

感謝您的時間,如果我正確理解3列的分割我必須調用函數3次例如SELECT [dbo]。[Split]( 'xx,yy,zz',',',1)會給xy賦予2 yy和3 zz。 – user9969

+0

是的。我想你在TSQL中使用它,這將是你能做的最好的事情。我更喜歡使用GetColumnValue而不是Split – Jade

+0

幹得好!我不需要這麼做,所以這很有用!我將結果加載到臨時表中,並且每次在循環中將列遞增1。最後,我用一個不存在的東西來找出什麼時候打破我的循環。 – jediCouncilor

1

在SQL Server中沒有Split()功能,但您可以創建用戶定義的函數。

看到這個答案How to split a comma-separated value to columns

+0

,感謝分割功能,但我如何使用它我的上下文,例如填補我在問題中談到的3列?對不起,如果明顯,但看不出你是如何做到的。這種分割只會讓我得到第一個逗號,那麼從firstcomma到第二個和最後一個呢? – user9969

+0

請參閱我的新發布的答案。希望你喜歡。 – Jade

0

創建下面的功能及使用方法如下

CREATE FUNCTION [dbo].[Split]  
( 
    @List nvarchar(2000),  
    @SplitOn nvarchar(5)  
)  
RETURNS @RtnValue table  
( 

    Id int identity(1,1),  
    Value nvarchar(100)  
)  
AS  
BEGIN  
    While (Charindex(@SplitOn,@List)>0)  
    Begin  

    Insert Into @RtnValue (value)  
    Select  
    Value = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1)))  

    Set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List))  
    End  

    Insert Into @RtnValue (Value)  
    Select Value = ltrim(rtrim(@List))  

    Return  
END 

SELECT TOP 1 * FROM dbo.Split(order,',') 
+0

似乎要返回一個表,我想要什麼。如果我通過SELECT * FROM [dbo]。[拆分]('xx,yy,zz',',')我得到一個id值的表我如何使用一個select語句來填充列,例如Select Name, 姓氏, FirstCommaColumn =? SecondCommaColumn =? ThirdColumnFromSecondCommaOnwards =? from myTable CROSS APPLY(SELECT TOP 1 * FROM dbo.Split(orderColumn,','))AS xx – user9969

0

它似乎是一個不錯的情況下,與PARSENAME玩。

編輯使用@Order爲例:

DECLARE @Order VARCHAR(MAX) = 'xxx,yyy,zzzz' 
SELECT FirstCommaColumn=PARSENAME(REPLACE(@Order,',','.'),3), 
     SecondCommaColumn=PARSENAME(REPLACE(@Order,',','.'),2), 
     ThirdColumnFromSecondCommaOnwards=PARSENAME(REPLACE(@Order,',','.'),1) 
0
CREATE FUNCTION [dbo].[splitStr] ( 

@str NVARCHAR(MAX), 

    @delimiter CHAR(1) 
) 

RETURNS @output TABLE(

    RowID smallint IDENTITY(1,1), 
    t1 NVARCHAR(MAX) , 
    t2 NVARCHAR(MAX) , 
    t3 NVARCHAR(MAX) , 
    t4 NVARCHAR(MAX) , 
    t5 NVARCHAR(MAX) , 
    t6 NVARCHAR(MAX) , 
    t7 NVARCHAR(MAX) , 
    t8 NVARCHAR(MAX) , 
    t9 NVARCHAR(MAX) , 
    t10 NVARCHAR(MAX) 
) 

begin 

    declare @st int, @en int, @xx int 
    declare @cntr int 

    set @cntr = 0 
    set @st = 1 
    select @en = CHARINDEX(@delimiter, @str, @st) 

    if @en = 0 
     set @en = LEN(@str) 

    while @en <= LEN(@str) and @cntr < 11 begin 
     set @cntr = @cntr + 1 
     set @xx = @en - @st 

     if @cntr = 1 
      insert into @output(t1) values(SUBSTRING(@str, @st, @xx)) 
     if @cntr = 2 
      update @output set t2 = SUBSTRING(@str, @st, @xx) 
     if @cntr = 3 
      update @output set t3 = SUBSTRING(@str, @st, @xx) 
     if @cntr = 4 
      update @output set t4 = SUBSTRING(@str, @st, @xx) 
     if @cntr = 5 
      update @output set t5 = SUBSTRING(@str, @st, @xx) 
     if @cntr = 6 
      update @output set t6 = SUBSTRING(@str, @st, @xx) 
     if @cntr = 7 
      update @output set t7 = SUBSTRING(@str, @st, @xx) 
     if @cntr = 8 
      update @output set t8 = SUBSTRING(@str, @st, @xx) 
     if @cntr = 9 
      update @output set t9 = SUBSTRING(@str, @st, @xx) 
     if @cntr = 10 
      update @output set t10 = SUBSTRING(@str, @st, @xx) 

     set @st = @en + 1 

     if @st > len(@str) 
      begin 
       set @en = @en + 100 
      end 
     else 
      begin  
       select @en = CHARINDEX(@delimiter,@str, @st) 
       if @en = 0 
        begin 
         set @en = LEN(@str) 
         set @xx = @en - @st 
        end 
      end 

    end 

    return 

end 

/*

這將允許您通過分隔符分裂到10場了。您可以添加更多的,如果你的需求超過列表10

使用

select * from TableName a 
cross apply splitStr(a.FiledName, ',') 

*/

2
Declare @str as Varchar(100) = '10|20|30|40|500|55' 
Declare @delimiter As Varchar(1)='|' 
Declare @Temp as Table (item varchar(100)) 
Declare @i as int=0 
Declare @j as int=0 
Set @j = (Len(@str) - len(REPLACE(@str,@delimiter,''))) 
While @i < = @j 
Begin 
    if @i < @j 
    Begin 
     Insert into @Temp 
     Values(SUBSTRING(@str,1,Charindex(@delimiter,@str,1)-1)) 
     set @str = right(@str,(len(@str)- Charindex(@Delominator,@str,1))) 
    End 
    Else 
    Begin 
    Insert into @Temp Values(@str) 
    End 

Set @i = @i + 1 
End 

Select * from @Temp