【问题标题】:How to split string into multiple in sql server如何在sql server中将字符串拆分为多个
【发布时间】:2017-01-16 09:21:12
【问题描述】:

我有一个如下所示的列数据,

126-35-56-24

我希望结果是这样的,

select 126 as Id, 35 as Age, 56 as EmpId, 24 as Day

我只是尝试使用substring,我可以将字符串拆分为 126 和 35-56-24,但我无法得到我想要的结果。

请帮我搞定这个。提前致谢...

【问题讨论】:

  • 在 SQL Server 2016 或更高版本中使用 STRING_SPLIT,否则您将需要自定义函数或带有子字符串和其他内容的非常丑陋的查询。
  • 为了让您的生活更轻松,请查看是否可以在将日期数据加载到 SQL Server 之前对其进行拆分。

标签: sql sql-server tsql sql-server-2012 substring


【解决方案1】:

蒂姆提到的一切......,

但是如果你需要一个分离器

Declare @String varchar(50) = '126-35-56-24'

Select ID    = max(case when Key_PS=1 then Key_Value else null end)
      ,Age   = max(case when Key_PS=2 then Key_Value else null end)
      ,EmpID = max(case when Key_PS=3 then Key_Value else null end)
      ,Day   = max(case when Key_PS=4 then Key_Value else null end)
 From  [dbo].[udf-Str-Parse](@String,'-')

返回

ID    Age   EmpID   Day
126   35    56      24

UDF

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--       Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')

Returns @ReturnTable Table (Key_PS int IDENTITY(1,1), Key_Value varchar(max))
As
Begin
   Declare @XML xml;Set @XML = Cast('<x>' + Replace(@String,@Delimeter,'</x><x>')+'</x>' as XML)
   Insert Into @ReturnTable Select ltrim(rtrim(String.value('.', 'varchar(max)'))) FROM @XML.nodes('x') as T(String)
   Return 
End

【讨论】:

    【解决方案2】:

    使用下面的脚本,它将根据'-'的字符索引分割字符串。

    DECLARE @data varchar(50)='126-35-56-24'
    
    SELECT 'SELECT '+ SUBSTRING(@data,1,CHARINDEX('-', @data)-1) + ' as Id, '
       +SUBSTRING(@data,CHARINDEX('-', @data)+1,CHARINDEX('-', @data,CHARINDEX('-',@data) + 1) -CHARINDEX('-', @data)-1)+ ' as Age, '
       +SUBSTRING(@data,CHARINDEX('-', @data,CHARINDEX('-',@data)+1)+1,CHARINDEX('-', @data,CHARINDEX('-', @data,CHARINDEX('-',@data)+1)+1) -CHARINDEX('-', @data,CHARINDEX('-',@data)+1)-1)+' as EmpId, '
       +SUBSTRING(@data,CHARINDEX('-', @data,CHARINDEX('-', @data,CHARINDEX('-',@data)+1)+1)+1,LEN(@data)-CHARINDEX('-', @data,CHARINDEX('-', @data,CHARINDEX('-',@data)+1)+1)+1) +' as Day'
    

    样本输出:

    【讨论】:

    • 感谢您的努力,但数据大小可能会有所不同。它可能像'66-35-546-4'。所以我想只使用'-'来分割。谢谢你..
    【解决方案3】:

    如果您使用的是 SQL Server 2016,则可以使用 string_split 函数

    declare @str varchar(20) = '126-35-56-24'
    
    select  id = max(case when rn=1 then value else null end)
        ,age =  max(case when rn=2 then value else null end)
        ,empId =  max(case when rn=3 then value else null end)
        ,[Day] =  max(case when rn=4 then value else null end)
        from (select row_number() over(order by (select 1)) as rn, value from string_split(@str, '-')) a
    

    【讨论】:

    • 我使用的是 SQL Server 2012
    • 您可以使用自定义拆分和替换 string_split 函数。如果没有,请告诉我。
    【解决方案4】:

    由于没有其他人提到它,您可以简单地使用PARSENAME 函数。它在 SQL Server 中可用已有一段时间了。它有一些限制,但它会处理您给出的示例中的任务。

    【讨论】:

      【解决方案5】:

      如果始终是 4 组数据,您可以使用 parsename

      我只是将 - 替换为 .让 parsename 完成剩下的工作。

      SELECT PARSENAME(Replace(Col,'-','.'), 1) AS 'Object Name' ID,    
             PARSENAME(Replace(Col,'-','.'), 2) AS 'Age',  
             PARSENAME(Replace(Col,'-','.'), 3) AS 'EmpID',  
             PARSENAME(Replace(Col,'-','.'), 4) AS 'Day'
      FROM YOURTABLE
      

      【讨论】:

        【解决方案6】:

        使用以下脚本:

        DECLARE @VAR VARCHAR(50)='126-35-56-24'
        SELECT [1] AS ID, [2] AS AGE,[3] AS EMPID,[4] as day
        FROM  (SELECT [1],[2],[3],[4]
           FROM    
              (SELECT ID,VAL FROM Spliter(@VAR,'-')) AS B
           PIVOT (MAX(VAL) FOR ID IN ([1],[2],[3],[4])
                 ) AS A
          ) AS C
        

        对于拆分:

        CREATE FUNCTION Spliter
        (
        @delimited nvarchar(max),
        @delimiter nvarchar(100)
        ) RETURNS @t TABLE
        (
         id int identity(1,1),
         val nvarchar(max)
        )
         AS
         BEGIN
         declare @xml xml
         set @xml = N'<root><r>' + replace(@delimited,@delimiter,'</r><r>') + '</r>       </root>'
        
         insert into @t(val)
         select
         r.value('.','varchar(max)') as item
         from @xml.nodes('//root/r') as records(r)
        
         RETURN
         END
         GO
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多