Sql server 两个分隔符(“”)之间的字符串

Sql server 两个分隔符(“”)之间的字符串,sql-server,string,substring,charindex,Sql Server,String,Substring,Charindex,我正在将一个字符串拆分为它的基本组件。我已经弄懂了第一部分,并且工作得很好 SELECT(SUBSTRING(Field,0,CHARINDEX('_',Field,0))) AS POS1 我目前遇到的问题是第二部分和第三部分。整个字符串的格式为;字符\字符\字符,其中每个字段都可以有不同数量的字符 SUBSTRING(Field, CHARINDEX('-',Field)+1, CHARINDEX('_',Field, CHARINDEX('_',Field)+1 - CHARINDEX(

我正在将一个字符串拆分为它的基本组件。我已经弄懂了第一部分,并且工作得很好

SELECT(SUBSTRING(Field,0,CHARINDEX('_',Field,0))) AS POS1
我目前遇到的问题是第二部分和第三部分。整个字符串的格式为;字符\字符\字符,其中每个字段都可以有不同数量的字符

SUBSTRING(Field, CHARINDEX('-',Field)+1, CHARINDEX('_',Field, CHARINDEX('_',Field)+1 - CHARINDEX('_',Field)-1)) AS POS2
这在某些情况下有效,但在其他情况下会被截断。我盯着这个看了这么久,我都看不见了

还有,我要处理第三个位置


欢迎您提供任何建议,说明为什么它会以应有的方式工作。

如果它总是由三部分组成,您可以使用带有replace和parsename的技巧:


如果始终是三个部分,则可以使用replace和parsename技巧:


我以前使用过REVERSE来处理路径和文件名,这里也有一些例子


我以前使用过REVERSE来处理路径和文件名,这里也有一些例子

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

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
试试这个, 我倾向于使用变量来获得位置和简单的过程

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
这应该起作用:

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
这应该起作用:

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
最终工作代码

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。

最终工作代码

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。

使用字符串拆分函数和变量分隔符非常理想,因为它可能与您使用下划线还是破折号进行拆分的函数重复?您既有CHARINDEX'-',字段+1,也有CHARINDEX'''''''u'字段。。。在你的query@Ven这是最糟糕的分割字符串的方法。这是非常低效的,因为循环会让它用一半长的字符串爬行。这是一个更好的选择。如果你不喜欢这一点,你可以找到很多其他的选择,看一看,使用带有变量分隔符的字符串分割函数非常理想,因为它可能是你用下划线还是破折号分割的重复?您既有CHARINDEX'-',字段+1,也有CHARINDEX'''''''u'字段。。。在你的query@Ven这是最糟糕的分割字符串的方法。这是非常低效的,因为循环会让它用一半长的字符串爬行。这是一个更好的选择。如果你不喜欢这一点,还有很多其他的选择可以选择。虽然它造成了我遇到的同样问题。当POS1只有3个时,它只显示POS2的4个。以此类推,它总是从POS1加1,即使列中间和结尾的长度是可变的,使用“u”分隔它们。我已经更新了它,我认为这一个真的做了你想要它做的。尽管如此,这是一个丑陋的解决方案;就这样。在休息期间,我设法找到了左右值的解决方案,这是我的最终代码;选择子字符串[field],0,CHARINDEX[field],0作为POS1,子字符串SUBSTRING[field],CHARINDEX[field]+1,LEN[field],0,CHARINDEX,SUBSTRING[field],CHARINDEX[field]+1,LEN[field],0作为POS2,右[field],CHARINDEX'''.',反转[field]-1作为POS3Close。虽然它造成了我遇到的同样问题。当POS1只有3个时,它只显示POS2的4个。以此类推,它总是从POS1加1,即使列中间和结尾的长度是可变的,使用“u”分隔它们。我已经更新了它,我认为这一个真的做了你想要它做的。尽管如此,这是一个丑陋的解决方案;就这样。在休息期间,我设法找到了左右值的解决方案,这是我的最终代码;选择子字符串[field],0,CHARINDEX[field],0作为POS1,子字符串子字符串[field],CHARINDEX[field]+1,LEN[field],0,CHARINDEX,子字符串[field],CHARINDEX[field]+1,LEN[field],0作为POS2,右[field],CHARINDEX'',反转[field]-1作为POS3