2013-07-31 102 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