【问题标题】:How to Split String by Character into Separate Columns in SQL Server如何在 SQL Server 中按字符将字符串拆分为单独的列
【发布时间】:2019-01-05 04:28:08
【问题描述】:

我在 SQL Server 中有一个字段,其中包含部分、乡镇和范围信息,每个字段用破折号分隔;例如:18-84-7。我希望将这些信息按每个单元、分区作为一个字段、乡镇作为一个字段和范围作为一个字段进行细分,例如:18 84 7

字符数不同。每个单元并不总是 2 个字符或 1 个字符,所以我认为最好的方法是用破折号分隔,但我不知道该怎么做。有没有办法在 SQL Server 中做到这一点?

谢谢!

【问题讨论】:

    标签: sql regex sql-server-2008-r2


    【解决方案1】:

    可能有几种不同的方法可以做到这一点,有些方法比其他方法更丑陋。这是一个:

    (注:dat = 字符串)

    select *,
      substring(dat,1,charindex('-',dat)-1) as Section,
      substring(dat,charindex('-',dat)+1,charindex('-',dat)-1) as TownShip,
      reverse(substring(reverse(dat),0,charindex('-',reverse(dat)))) as myRange
    from myTable
    

    【讨论】:

    • 第一部分长度小于第二部分的列存在一些问题。例如 :set @text ='mark.sydney.iro' ,然后 select substring(@text,charindex('.',@text)+1,charindex('.',@text)-1) 得到不正确的值
    • @BWS 有时我的字符串需要填充 2 或 3 个值(addressline1、addressline2、addessline3)。使用您提供的示例,如果只有 2 个值填充我的 line3 = line2。我怎样才能防止这种情况发生?
    【解决方案2】:

    请尝试更可靠的代码

    创建下面的函数

    CREATE FUNCTION dbo.UFN_SEPARATES_COLUMNS(
     @TEXT      varchar(8000)
    ,@COLUMN    tinyint
    ,@SEPARATOR char(1)
    )RETURNS varchar(8000)
    AS
      BEGIN
           DECLARE @POS_START  int = 1
           DECLARE @POS_END    int = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
    
           WHILE (@COLUMN >1 AND @POS_END> 0)
             BEGIN
                 SET @POS_START = @POS_END + 1
                 SET @POS_END = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
                 SET @COLUMN = @COLUMN - 1
             END 
    
           IF @COLUMN > 1  SET @POS_START = LEN(@TEXT) + 1
           IF @POS_END = 0 SET @POS_END = LEN(@TEXT) + 1 
    
           RETURN SUBSTRING (@TEXT, @POS_START, @POS_END - @POS_START)
      END
    GO
    

    然后试试下面的代码

    DECLARE @STRING VARCHAR(20) ='1-668-333'
    SELECT
      dbo.UFN_SEPARATES_COLUMNS(@STRING, 1, '-') AS VALUE1,
      dbo.UFN_SEPARATES_COLUMNS(@STRING, 2, '-') AS VALUE2,
      dbo.UFN_SEPARATES_COLUMNS(@STRING, 3, '-') AS VALUE3
    

    结果

    如果您需要更多了解,请前往

    https://social.technet.microsoft.com/wiki/contents/articles/26937.t-sql-splitting-a-string-into-multiple-columns.aspx

    【讨论】:

      【解决方案3】:

      你可以使用这样的东西(@canon 发布)

      CREATE FUNCTION [dbo].[Split]
      (   
       @String varchar(max)
      ,@Delimiter char
      )
      RETURNS @Results table
      (
       Ordinal int
      ,StringValue varchar(max)
      )
      as
      begin
      
          set @String = isnull(@String,'')
          set @Delimiter = isnull(@Delimiter,'')
      
          declare
           @TempString varchar(max) = @String
          ,@Ordinal int = 0
          ,@CharIndex int = 0
      
          set @CharIndex = charindex(@Delimiter, @TempString)
          while @CharIndex != 0 begin     
              set @Ordinal += 1       
              insert @Results values
              (
               @Ordinal
              ,substring(@TempString, 0, @CharIndex)
              )       
              set @TempString = substring(@TempString, @CharIndex + 1, len(@TempString) - @CharIndex)     
              set @CharIndex = charindex(@Delimiter, @TempString)
          end
      
          if @TempString != '' begin
              set @Ordinal += 1 
              insert @Results values
              (
               @Ordinal
              ,@TempString
              )
          end
      
          return
      end
      

      更多信息请查看How to split string using delimiter char using T-SQL?

      【讨论】:

        【解决方案4】:
        DROP PROCEDURE getName
        GO
        create proc getName as
        begin
        select * , substring(name, 1 , CHARINDEX(' ', name)-1) as 'First Name',
        SUBSTRING(name, CHARINDEX(' ', name)+1, len(name)) as 'Last Name' 
        from Employee 
        order by [Last Name]
        end
        go
        exec getName
        

        【讨论】:

          【解决方案5】:

          最好把BWS回答的第二部分换成这个:

          select SUBSTRING(dat,CHARINDEX('-', dat) + 1,LEN(dat) - CHARINDEX('-', dat) - CHARINDEX('-', REVERSE(dat)) ) from myTable.
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-01-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-03-09
            • 2018-03-28
            相关资源
            最近更新 更多