【问题标题】:Split function by comma in SQL Server 2008SQL Server 2008 中的逗号分割函数
【发布时间】:2013-12-29 01:19:28
【问题描述】:

我知道这个问题已被问过很多次,但找不到我需要的。

我有此列“订单”,其中包含以下格式的数据。 '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 做到这一点? 如果有所作为,此选择是视图的一部分

【问题讨论】:

  • sql server中没有Split()函数
  • Jade,我知道我没有在寻找一个可以满足我需要的东西或一些代码来拆分列。
  • 最好不要尝试将多个数据项存储在单个列中。
  • @user231465,是的,对不起,我把我的答案移到下面。
  • @Damien_The_Unbeliever,我没有选择将这个数据库导入我们的系统。

标签: sql sql-server-2008 tsql split


【解决方案1】:

我已更改函数名称,因此它不会与 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)

【讨论】:

  • 感谢您的宝贵时间,如果我理解正确以拆分 3 列,我必须调用该函数 3 次,例如 SELECT [dbo].[Split] ('xx, yy,zz', ',',1) 会给 xx 2 yy 和 3 zz 。
  • 是的。我认为你在 TSQL 中使用它,所以这将是你能做的最好的事情。我更喜欢使用 GetColumnValue 而不是 Split
  • 干得好!我有一段时间不需要这样做了,所以这很有用!我将结果加载到一个临时表中,并在每次循环中将列增加 1。最后,我使用了 not exists 来找出何时中断我的循环。
【解决方案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 

【讨论】:

    【解决方案3】:

    SQL Server 中没有Split() 函数,但您可以创建用户定义函数。

    看到这个答案How to split a comma-separated value to columns

    【讨论】:

    • ,感谢拆分功能,但我如何在上下文中使用它,例如填充我在问题中谈到的 3 列?很抱歉,如果很明显但看不到你是如何做到的。那个拆分只会给我第一个逗号,从第一个逗号到第二个和最后一个呢?
    • 请看我新发布的答案。希望你喜欢它。
    【解决方案4】:

    创建下面的函数并如下使用

    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,',')
    

    【讨论】:

    • 这似乎返回了一个表和我想要的。如果我通过 SELECT * FROM [dbo].[Split] ('xx, yy,zz',',') 我得到一个表id 值如何在 select 语句中使用来填充列,例如 Select Name、Surname、FirstCommaColumn=?第二逗号列=? ThirdColumnFromSecondCommaOnwards=? from myTable CROSS APPLY (SELECT TOP 1 * FROM dbo.Split(orderColumn,',')) AS xx
    【解决方案5】:

    使用 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)
    

    【讨论】:

    • 线程显式命名 SQL Server 2008,它没有那个功能。
    【解决方案6】:
    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, ',')
    

    */

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-03-18
      相关资源
      最近更新 更多