SQL Server:如何在最后一次出现另一个子字符串之后和下一个逗号之前找到子字符串

时间:2021-01-15 10:19:30

标签: sql-server request substring

我在 SQL Server 数据库中有一个表,其中有一列 ColumnStrings 包含此类字符串:

"AB=ikkw0116,AC=BE D Work stations,AC=BE D stations,AC=D Allocated,AD=pnser,AD=pnsas,AD=owned,AD=increased"
"AB=ikkWA001S1,AC=BE D HD,AC=D Allocated,AD=pnser,AD=pnsas,AD=owned,AD=increased"
"AB=iksw0084,AC=Domain View,AD=pnsas,AD=owned,AD=increased"
"AB=GHRS05900263,AC=Big stations,AC=GHR,AC=BE,AD=ger,AD=eu,AD=intra"

所以我们有一个随机数 AB=AC=AD=

我想在最后一次出现 AC= 之后获取值(位于等号之后和下一个昏迷之前的子字符串)。

在我的示例中,搜索的值将针对这 4 个字符串:

"D Allocated"
"D Allocated"
"Domain View"
"BE"

我可以用

找到最后一次出现的位置
DATALENGTH(MyTable.[ColumnStrings])-CHARINDEX(REVERSE('=AC'),REVERSE(MyTable.[ColumnStrings]))-1

但是如何在此 =AC 之后和下一个逗号之前获取子字符串(如果我们找不到任何逗号,则为字符串的末尾)

2 个答案:

答案 0 :(得分:1)

请不要考虑尝试在您的生产数据库上执行此操作。相反,正如上面的评论所建议的,在将 AD 数据引入 SQL Server 之前对其进行规范化。特别是,SQL Server 的正则表达式支持很差/没有,这正是您在这里真正需要的。为此,这里有一个正则表达式模式,您可以使用它来提取键 AC 的最终值:

^.*\bAC=([^,]+)

Demo

您可以将此正则表达式应用于您的数据,然后重新导入。

答案 1 :(得分:1)

在像您这样的情况下,基于 JSON 的方法是一种可能的选择。您需要将输入字符串适当地转换为有效的 JSON 结构 - 嵌套的 JSON 数组(AB=iksw0084,AC=Domain View,AD=pnsas,AD=owned,AD=increased[["AB","iksw0084"],["AC","Domain View"],["AD","pnsas"],["AD","owned"],["AD","increased"])。然后您需要使用 OPENJSON() 和默认架构解析此 JSON。结果是一个包含 keyvaluetype 列的表,如果是数组,key 列包含数组中每个项目的从 0 开始的索引。想法是将此索引用于 ORDER BY 调用中的 ROW_NUMBER() 子句。

表格:

SELECT ColumnStrings
INTO Data
FROM (VALUES 
   ('AB=ikkw0116,AC=BE D Work stations,AC=BE D stations,AC=D Allocated,AD=pnser,AD=pnsas,AD=owned,AD=increased'),
   ('AB=ikkWA001S1,AC=BE D HD,AC=D Allocated,AD=pnser,AD=pnsas,AD=owned,AD=increased'),
   ('AB=iksw0084,AC=Domain View,AD=pnsas,AD=owned,AD=increased'),
   ('AB=GHRS05900263,AC=Big stations,AC=GHR,AC=BE,AD=ger,AD=eu,AD=intra')
) v (ColumnStrings)

声明:

SELECT j.StringValue
FROM Data d
OUTER APPLY (
   SELECT 
      j1.[value], 
      JSON_VALUE([value], '$[0]') AS StringKey, 
      JSON_VALUE([value], '$[1]') AS StringValue,
      ROW_NUMBER() OVER (
         PARTITION BY JSON_VALUE([value], '$[0]') 
         ORDER BY CONVERT(int, [key]) DESC
      ) AS RN
   FROM OPENJSON(CONCAT('[["', REPLACE(REPLACE(d.ColumnStrings, ',', '"],["'), '=', '","'), '"]]')) j1
) j
WHERE j.StringKey = 'AC' AND j.RN = 1

结果:

StringValue
-----------
D Allocated
D Allocated
Domain View
BE
相关问题