2013-07-31 80 views
8

我有一个包含如下字符串的列的表。可变长度的子串

RTSPP_LZ_AEN 
RTSPP_LZ_CPS 
RTSPP_LZ_HOUSTON 
RTSPP_LZ_LCRA 
RTSPP_LZ_NORTH 
RTSPP_LZ_RAYBN 
RTSPP_LZ_SOUTH 
RTSPP_LZ_WEST 
RTSPP_BTE_CC1 
RTSPP_BTE_PUN1 
RTSPP_BTE_PUN2 

我需要从_直到字符串的结束第二次出现得到子,正如你所看到的子串的长度是固定的不是。第一部分并不总是可以修改的。截至目前,我正在使用下面的代码来实现它。

SELECT SUBSTRING([String],CHARINDEX('_',[String],(CHARINDEX('_',[String])+1))+1,100) 
FROM [Table] 

正如你可以看到我正在采取任意大的值作为长度来照顾变长。有没有更好的方法来做到这一点?

+0

总是会有2个下划线吗? –

+0

第一部分始终是RTSPP_LZ_还是可能有其他值? –

+0

@AaronBertrand截至目前我还没遇到超过2个下划线的情况。将来可能会出现这种情况,最后一个下划线直到字符串结尾。它可以处理下划线的第n次出现将是一个更通用的解决方案不胜感激 – Ram

回答

11

您可以结合使用CHARINDEXREVERSE功能找到最后出现_,并且您可以使用RIGHT从字符串的末尾获取指定数量的字符。

SELECT RIGHT([String],CHARINDEX('_',REVERSE([String]),0)-1) 

SQLFiddle DEMO

+0

感谢您的简单解决方案和演示 – Ram

6

你可以尝试给LEN([字符串])作为最后一个参数:

SELECT SUBSTRING([String],CHARINDEX('_',[String],(CHARINDEX('_',[String])+1))+1,len([string])) FROM [Table] 
+0

1感谢改变提的LEN([字符串])。我完全忘了它。 – Ram

0

或者说,即使是这样:

SELECT SUBSTRING([String],CHARINDEX('_',[String],(CHARINDEX('_',[String])+1))+1, 
      LEN([String])-CHARINDEX('_',[String])+1) 
1

你可以使用一个公用表表达式做像下面的代码工作。无论字符串中有多少个下划线,都可以灵活地获取所有子字符串。

;WITH cte AS (
    SELECT 
     0 AS row 
     ,CHARINDEX('_', [String]) pos 
     ,[String] 
    FROM [Table] 
    UNION ALL 
    SELECT 
     row + 1 
     ,CHARINDEX('_', [String], pos + 1) 
     ,[String] 
    FROM cte 
    WHERE pos > 0 
) 
SELECT 
    row 
    ,[String] 
    ,pos 
    ,SUBSTRING([String], pos + 1, LEN([String]) -pos) 
FROM cte 
WHERE pos > 0 
-- Remove line below to see all possible substrs 
    AND row = 1 
ORDER BY 
    [String], pos 
+0

+1感谢您的答案,它甚至可以处理零下划线时的情况,但我不能使用CTE,因为这是一个更大的查询的一小部分 – Ram