一列中有一个逗号分隔的字符串,看起来像
test=1,value=2.2,system=321
我想从字符串中提取值。我可以使用select PatIndex('%value=%',columnName)
然后使用left,但这只能找到patindex的开头。
如何识别模式结束值=%,以便我们可以提取出该值?
答案 0 :(得分:2)
用SUBSTRING
和您的CHARINDEX
绑一些PATHINDEX
。
DECLARE @text VARCHAR(100) = 'test=1,value=2.21954,system=321'
SELECT
Original = @text,
Parsed = SUBSTRING( -- Get a portion of the original value
@text,
PATINDEX('%value=%',@text) + 6, -- ... starting from the 'value=' (without the 'value=')
-1 + CHARINDEX( -- ... and get as many characters until the first comma
',',
SUBSTRING( -- ... (find the comma starting from the 'value=' onwards)
@text,
PATINDEX('%value=%',@text) + 6,
100)))
结果:
Original Parsed
test=1,value=2.2,system=321 2.2
请注意,如果CHARINDEX
之后没有逗号,则value=
将失败。您可以使用WHERE
进行过滤。
我强烈建议您将已分割的值存储在适当的表上,这样就不必处理字符串噩梦了。
答案 1 :(得分:1)
您可以使用CHARINDEX
作为起始位置来查找模式之后的第一个逗号 。 CROSS APPLY
用于使查询更易于阅读:
WITH tests(str) AS (
SELECT 'test=1,value=2.2,system=321'
)
SELECT str, substring(str, pos1, pos2 - pos1) AS match
FROM tests
CROSS APPLY (SELECT PATINDEX('%value=%', str) + 6) AS ca1(pos1)
CROSS APPLY (SELECT CHARINDEX(',', str, pos1 + 1)) AS ca2(pos2)
-- 2.2
答案 2 :(得分:1)
首先,如果要查询非规范化数据,则不要使用这种方法存储非规范化数据。 SQL语言不擅长字符串操作。解析和拆分字符串也不能利用索引,这意味着任何试图查找例如引用system 321
的所有记录的查询都必须扫描并解析所有行。>
SQL Server 2016和JSON
SQL Server 2016添加了对JSON和STRING_SPLIT
函数的支持。早期版本已经提供了XML类型。最好将复杂值存储为JSON或XML,而不要尝试解析字符串。
一种选择是将字符串转换为JSON对象并检索value
的内容,例如:
DECLARE @text VARCHAR(100) = 'test=1,value=2.2,system=321'
select json_value('{"' + replace(replace(@text,',','","'),'=','":"') + '"}','$.value')
这将返回2.2
。
替换项将原始字符串转换为
{"test":"1","value":"2.2","system":"321"}
JSON_VALUE(@json,'$.')
将返回该对象的value
属性
SQL Server的早期版本
在早期的SQL Server版本中,您可以通过相同的方式将该字符串转换为XML元素并使用XQuery:
DECLARE @text VARCHAR(100) = 'test=1,value=2.2,system=321';
declare @xml varchar(100)='<r ' + replace(replace(@text,',','" '),'=',' ="') + '" />';
select @xml
select cast(@xml as xml).value('(/r[1]/@value)','varchar(20)')
在这种情况下,@xml
包含:
<r test ="1" value ="2.2" system ="321" />
查询结果为2.2
答案 3 :(得分:0)
您可以尝试以下操作。
DECLARE @xml AS XML
SELECT @xml = Cast(( '<X>' + Replace(txt, ',', '</X><X>') + '</X>' ) AS XML)
FROM (VALUES ('test=1,value=2.2,system=321')) v(txt)
SELECT LEFT(value, Charindex('=', value) - 1) AS LeftPart,
RIGHT(value, Charindex('=', Reverse(value)) - 1) AS RightPart
FROM (SELECT n.value('.', 'varchar(100)') AS value
FROM @xml.nodes('X') AS T(n))T
输出
+----------+-----------+
| LeftPart | RightPart |
+----------+-----------+
| test | 1 |
+----------+-----------+
| value | 2.2 |
+----------+-----------+
| system | 321 |
+----------+-----------+
答案 4 :(得分:0)
如果您使用的是SQL Server(2016或更高版本),则可以尝试以下查询
SELECT RIGHT(Value,CHARINDEX('=',REVERSE(Value))-1) FROM YourTableName
CROSS APPLY STRING_SPLIT ( ColumnName , ',' )
WHERE Value Like 'Value=%'