SQL Server从字符串中提取特定值,该值可以包含重复项/空值

时间:2017-06-05 21:24:19

标签: sql sql-server regex string

我正在尝试找到从字符串中提取特定值的最佳方法,该字符串可以包含值的空值/重复项。问题是我必须在查询中执行此操作,并将这些值拉入视图以供使用。

字符串示例:

ABCD: 123 EFG: 03 HIJ: NGAB XYZ:  XYZ: 133
EFG: 03 HIJ: NGAB XYZ: 133

我正在尝试提取ABCDEFGHIJXYZ的值。

例如,第一个字符串应返回:

123 (for value of ABCD)
03 (for value of EFG)
NGAB (for value of HIJ)
133 (for value of XYZ)

第二个字符串应该返回:

NULL (for value of ABCD)
03 (for value of EFG)
NGAB (for value of HIJ)
133 (for value of XYZ)

要返回的值的长度始终是静态的(即ABCD将始终为ABCD,123将始终为要返回的值的长度 - 即3个字符。同样适用于EFG和03 - EFG将始终为EFG和03将始终为2个字符,依此类推)。

我正在尝试使用以下内容尝试返回我的值:

SELECT substring(replace(replace(TEMPFIELD,' ',''),':',''), charindex('XYZ',replace(replace(TEMPFIELD,' ',''),':',''))+3,3) AS XYZ FROM MYTABLE

我按字段更改查询并根据需要调整子字符串的长度。问题是当存在重复时,我返回错误的值,当有空值时,我返回错误的值。

例如,我的查询返回XYZ作为第一个字符串中XYZ的值而不是123。它还返回03H作为第二个字符串中ABCD的值而不是NULL。在这种情况下,我是否有更好的功能来处理空值/重复的两种情况?

更新了查询:

SELECT CASE WHEN TEMPFIELD LIKE '%XYZ%XYZ%' 
            THEN     substring(stuff(replace(replace(TEMPFIELD ,' ',''),':',''),charindex('XYZ',replace(replace(TEMPFIELD ,' ',''),':','')),3,''), charindex('XYZ',stuff(replace(replace(TEMPFIELD ,' ',''),':',''),charindex('XYZ',replace(replace(TEMPFIELD ,' ',''),':','')),3,''))+3,3)
       WHEN TEMPFIELD LIKE '%XYZ%' 
            THEN  substring(replace(replace(TEMPFIELD ,' ',''),':',''), charindex('XYZ',replace(replace(TEMPFIELD ,' ',''),':',''))+3,3) 
       ELSE NULL 
  END AS XYZ

1 个答案:

答案 0 :(得分:0)

理想情况下,如果你能想要整理你试图传递的字符串,因为这可能会非常混乱,但我可以根据以下假设为你提供这个解决方案:

  • 重复键仅按照您的示例出现两次
  • 值不能包含密钥
  • 当密钥重复时,最后一个是你想要的值。
  CASE WHEN TEMPFIELD LIKE '%XYZ%XYZ%' 
            THEN SUBSTRING(TEMPFIELD, CHARINDEX('XYZ: ', TEMPFIELD, CHARINDEX('XYZ: ', TEMPFIELD) + 1) + 5, 3)
       WHEN TEMPFIELD LIKE '%XYZ%' 
            THEN SUBSTRING(TEMPFIELD, CHARINDEX('XYZ: ', TEMPFIELD) + 5, 3) 
       ELSE NULL 
  END AS XYZ

如果您真的需要添加替换,但如果您知道格式足够可靠,则不应该这样做,因为它只会增加处理时间。

要解释这有什么作用:第一个case语句将通过获取第二个键的CHARINDEX来处理重复的值,如果那个案例标准不匹配那么它将落到第二个案例并且做一些类似于你已经做过的事情,最后如果字符串与其中任何一个都不匹配,它只会给你null。