【问题标题】:String Between Two delimiters ('_')两个分隔符之间的字符串 ('_')
【发布时间】:2019-04-05 16:14:55
【问题描述】:

我正在将字符串拆分为其基本组件。我已经弄清楚了第一部分并且工作正常;

SELECT(SUBSTRING(Field,0,CHARINDEX('_',Field,0))) AS POS1

我目前遇到的问题是第二和第三部分。整个字符串的格式是; character_character_character(其中每个字段都可以包含不同数量的字符)。

SUBSTRING(Field, CHARINDEX('-',Field)+1, CHARINDEX('_',Field, CHARINDEX('_',Field)+1 - CHARINDEX('_',Field)-1)) AS POS2

这在某些情况下有效,但在其他情况下会截断。我一直盯着这个看太久了,以至于我对解决方案视而不见。

另外,要解决第三个位置。

欢迎任何关于为什么它会按应有的方式工作的建议。

【问题讨论】:

标签: sql-server string substring charindex


【解决方案1】:

最终的工作代码;

SELECT (SUBSTRING([field],0,CHARINDEX('_',[field],0))) AS POS1
, SUBSTRING(SUBSTRING([field], CHARINDEX('_',[field])+1, LEN([field])), 0, CHARINDEX('_',SUBSTRING([field], CHARINDEX('_',[field])+1, LEN([field])),0)) AS POS2
, RIGHT([field],CHARINDEX('_',REVERSE([field]))-1) AS POS3
FROM TableName

谢谢大家,尤其是 Sorix。

【讨论】:

    【解决方案2】:

    这应该可行:

    SELECT Field, SUBSTRING(Field,0,CHARINDEX('_',Field,0)) AS POS1, 
    SUBSTRING(SUBSTRING(Field, CHARINDEX('_',Field)+1, LEN(Field)), 0, CHARINDEX('_',SUBSTRING(Field, CHARINDEX('_',Field)+1, LEN(Field)),0)) AS POS2 ,
    SUBSTRING(Field, 3 + LEN(SUBSTRING(Field,0,CHARINDEX('_',Field,0))) + LEN(SUBSTRING(SUBSTRING(Field, CHARINDEX('_',Field)+1, LEN(Field)), 0, CHARINDEX('_',SUBSTRING(Field, CHARINDEX('_',Field)+1, LEN(Field)),0))), LEN(Field))  AS POS3
    FROM YOUR_TABLE
    

    【讨论】:

    • 关闭。虽然它产生了我遇到的同样的问题。当 POS1 只有 3 个时,它只显示来自 POS2 的 4 个。依此类推,它总是从 POS1 加 1,即使列(中间和结尾)的长度是可变的,使用 '_' 来分隔它们。
    • 我已经更新了它,我认为这个确实可以满足您的需求。话虽这么说,这是一个丑陋的解决方案;)
    • 就是这样。在“休息”期间,我确实设法找到了左右值的解决方案,这是我拥有的最终代码; SELECT (SUBSTRING([field],0,CHARINDEX('',[field],0))) AS POS1 , SUBSTRING(SUBSTRING([field], CHARINDEX('',[field]) +1, LEN([field])), 0, CHARINDEX('',SUBSTRING([field], CHARINDEX('',[field])+1, LEN([field])) ,0)) AS POS2 , RIGHT([field],CHARINDEX('_',REVERSE([field]))-1) AS POS3
    【解决方案3】:

    试试这个, 我倾向于使用变量来获取位置和简单的过程

    declare @field varchar(300) =  'character1_character2_character3'
    declare @char1Pos int =  CHARINDEX('_',@field,0)
    
    --select @char1Pos
    declare @char2Pos int = (CHARINDEX('_',@field)+@char1Pos + 1) -1
    --select @char2Pos
    
    select  (SUBSTRING(@field,0,@char1Pos)) AS POS1,
    SUBSTRING(@field, -- field
              @char1Pos+ 1,--starting position for POS2
              (@char2Pos -1) - @char1Pos) --ENDING POSITION FOR POS2
              AS POS2,
         substring(@field,-- field
                    ((@char2Pos +1) ),--starting position for POS3
                    len(@field) - ((@char2Pos -1) - @char1Pos))--ENDING POSITION FOR POS2
                     as POS3
    

    【讨论】:

      【解决方案4】:

      我以前用 REVERSE 对路径和文件名做类似的事情。还有一些例子Here

      DECLARE @full VARCHAR(MAX)
      SET @full = 'c:\windows\system\sub-folder\somefile_file-stuff.qqq'
      SELECT SUBSTRING(@full, 1, LEN(@full)-(CHARINDEX('\',REVERSE(@full))-1)) AS Path
      

      【讨论】:

        【解决方案5】:

        如果总是三部分,您可以使用 replaceparsename 的技巧:

        SELECT PARSENAME(val, 3) As col1,
               PARSENAME(val, 2) As col2,
               PARSENAME(val, 1) As col3
        FROM Table
        CROSS APPLY
        (
            SELECT REPLACE(Col, '_', '.') As val
        ) x
        

        【讨论】:

          猜你喜欢
          • 2012-04-27
          • 2014-12-08
          • 1970-01-01
          • 2012-06-23
          • 2017-03-17
          • 1970-01-01
          • 2018-11-25
          • 2016-02-10
          • 1970-01-01
          相关资源
          最近更新 更多