我有一个这样的字符串:
`a|b^c|d|e^f|g`
我希望保持管道分隔,但删除胡萝卜子分隔,只保留该子分隔符的第一个值。
输出结果为:
`a|b|d|e|g`
有没有办法用简单的SQL函数来做到这一点?
答案 0 :(得分:3)
另一种选择,使用CHARINDEX
,REPLACE
和SUBSTRING
:
DECLARE @OriginalString varchar(50) = 'a|b^c^d^e|f|g'
DECLARE @MyString varchar(50) = @OriginalString
WHILE CHARINDEX('^', @MyString) > 0
BEGIN
SELECT @MyString = REPLACE(@MyString,
SUBSTRING(@MyString,
CHARINDEX('^', @MyString),
CASE WHEN CHARINDEX('|', @MyString, CHARINDEX('^', @MyString)) > 0 THEN
CHARINDEX('|', @MyString, CHARINDEX('^', @MyString)) - CHARINDEX('^', @MyString)
ELSE
LEN(@MyString)
END
)
, '')
END
SELECT @OriginalString As Original, @MyString As Final
输出:
Original Final
a|b^c^d^e|f|g a|b|f|g
答案 1 :(得分:2)
此表达式将替换插入符号的第一个实例,直到后续管道(或字符串结尾)。您可以只运行一个循环,直到不再更新行或在函数内找不到更多插入符号等。
case
when charindex('^', s) > 0
then stuff(
s,
charindex('^', s),
charindex('|', s + '|', charindex('^', s) + 1) - charindex('^', s),
''
)
else s
end
这是一个可以适应函数定义的循环:
declare @s varchar(30) = 'a|b^c^d|e|f^g|h^i';
declare @n int = charindex('^', @s);
while @n > 0
begin
set @s = stuff(@s, @n, charindex('|', @s + '|', @n + 1) - @n, '');
set @n = charindex('^', @s, @n + 1);
end
select @s;
需要谨慎处理字符串的尾部,因为它不会成为最终的管道分隔符。你可以看到我已经处理过了。
答案 2 :(得分:2)
首先拆分由|
分隔的值,然后提取第一个值并将结果连接起来以获得结果
试试这个
SELECT Cast(left(intr,len(intr)-1) AS VARCHAR(1000)) AS res
FROM (SELECT LEFT(split_val, Isnull(NULLIF(Charindex('^', split_val), 0)-1, Len(split_val))) + '|'
FROM Udf_splitstring('a|bdd^c|d|e^f|g', '|')
FOR xml path (''))a (intr)
结果: a|bdd|d|e|g
以下是有关拆分字符串函数 Split strings the right way – or the next best way
的文章