Sql server SQL Server:如何在上一次出现另一个子字符串之后、下一个逗号之前找到该子字符串
我在SQL Server数据库中有一个表,其中有一列Sql server SQL Server:如何在上一次出现另一个子字符串之后、下一个逗号之前找到该子字符串,sql-server,request,substring,Sql Server,Request,Substring,我在SQL Server数据库中有一个表,其中有一列ColumnStrings,其中包含此类字符串: “AB=ikkw0116,AC=BE D工作站,AC=BE D工作站,AC=D已分配,AD=pnser,AD=pnsas,AD=owned,AD=increased” “AB=ikkWA001S1,AC=BE D HD,AC=D分配,AD=pnser,AD=pnsas,AD=owned,AD=increased” AB=iksw0084,AC=域视图,AD=PNSA,AD=owned,AD=in
ColumnStrings
,其中包含此类字符串:
“AB=ikkw0116,AC=BE D工作站,AC=BE D工作站,AC=D已分配,AD=pnser,AD=pnsas,AD=owned,AD=increased”
“AB=ikkWA001S1,AC=BE D HD,AC=D分配,AD=pnser,AD=pnsas,AD=owned,AD=increased”
AB=iksw0084,AC=域视图,AD=PNSA,AD=owned,AD=increased
“AB=GHRS05900263,AC=大型电台,AC=GHR,AC=BE,AD=ger,AD=eu,AD=intra”
所以我们有一个随机数AB=
,AC=
和AD=
我想在最后一次出现AC=
之后获取值(放置在等号之后和下一个coma之前的子字符串)
在我的示例中,搜索的值将用于以下4个字符串:
“D已分配”
“D已分配”
“域视图”
“是”
我可以找到最后一次发生的位置
DATALENGTH(MyTable.[ColumnStrings])-CHARINDEX(REVERSE('=AC'),REVERSE(MyTable.[ColumnStrings])-1
但是如何在这个
=AC
之后和下一个逗号之前(或者如果我们找不到任何逗号,则在字符串的末尾)获取子字符串请不要考虑尝试在生产数据库上执行此操作。相反,正如上面的评论所建议的,在将广告数据引入SQL Server之前,请对其进行规范化。特别是,SQL Server对正则表达式的支持很差/没有,这正是您在这里真正需要的。为此,这里有一个regex模式,您可以使用它来提取keyAC
的最终值:
^.*\bAC=([^,]+)
您可以将此正则表达式应用于您的数据,然后可能重新导入。请不要考虑尝试在生产数据库上执行此操作。相反,正如上面的评论所建议的,在将广告数据引入SQL Server之前,请对其进行规范化。特别是,SQL Server对正则表达式的支持很差/没有,这正是您在这里真正需要的。为此,这里有一个regex模式,您可以使用它来提取key
AC
的最终值:
^.*\bAC=([^,]+)
您可以将此正则表达式应用于数据,然后可能重新导入。在类似您的情况下,基于JSON的方法是一种可能的选择。您需要将输入字符串适当地转换为一个有效的JSON结构-一个嵌套的JSON数组(
AB=iksw0084,AC=Domain View,AD=pnsas,AD=owned,AD=increated
转换为[[“AB”,“iksw0084”],[“AC”,“Domain View”],[“AD”,“owned”],[“AD”,“increated”]
)。然后您需要使用OPENJSON()解析这个JSON
和默认模式。结果是一个包含列key
、value
和type
的表,如果是数组,则key
列保存数组中每个项的基于0的索引。其思想是将此索引用于行号()调用中的ORDER BY
子句
表:
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
在像您这样的情况下,基于JSON的方法是一种可能的选择。您需要将输入字符串适当地转换为一个有效的JSON结构-一个嵌套的JSON数组(AB=iksw0084,AC=Domain View,AD=pnsas,AD=owned,AD=increated
,转换为[“AB”,“iksw0084”],[“AC”,“Domain View”],[“AD”,“pnsas”],[“AD”,“owned”],[“AD”,“increated”]
)。然后需要使用OPENJSON()解析此JSON
和默认模式。结果是一个包含列key
、value
和type
的表,如果是数组,则key
列保存数组中每个项的基于0的索引。其思想是将此索引用于行号()调用中的ORDER BY
子句
表:
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
听起来你需要修复你的设计;首先不要在你的RDBMS中存储这样的数据。规范化你的设计。你能先预处理你的数据吗。它看起来有一个很好的规则结构。@Lamu它不是我的数据库,我必须对它进行处理:)当然,这是一种奇怪的存储方式。@是的,我们有一个动态结构,b但我不想让列包含所有出现的内容,只需要得到一个子字符串,我想它可以在一行(但很长的一行:)中实现,就像子字符串一样(从最后一次出现的位置(我在上面写的行中有这个位置),直到下一个逗号或字符串结尾)@Jonathan如果你想ping某人,你需要正确拼写他们的显示名称。:)听起来你需要修复你的设计;首先不要在你的RDBMS中存储这样的数据。规范化你的设计。你能先预处理你的数据吗。它看起来有一个很好的规则结构。@Lamu它不是我的数据库,我必须处理它n it:)当然,这是一种奇怪的存储方式。@是的,我们有一个动态结构,但我不想让列包含所有发生的事件,只要得到一个子字符串,我想它可以在一行(但很长的一行:)中完成,就像子字符串(从最后一次发生的位置开始)(我在上面写的那行中有),直到下一个逗号或字符串结尾)@Jonathan如果你想ping某人,你需要正确拼写他们的显示名称。:)非常感谢你的回答,你的正则表达式工作得很好,但我真的更愿意在一个请求中立即提取这些数据,即使它没有很多子字符串、patindex、charindex函数,因为我没有访问权限我只是有一个sql请求要做,我正在尝试在不声明变量的情况下执行它,因为我不太知道如何执行函数等。我应该学习吗?非常感谢这个答案,您的正则表达式工作得非常好,但我真的更愿意在一个请求中立即提取这些数据,即使它不是很干净,有很多子字符串,patindex,charindex函数,因为我不知道