SQL 删除两个字符之间的字符串

5

我有一个类似这样的字符串:

`a|b^c|d|e^f|g`

我希望保留使用管道“|”作为分隔符,但删除脱字符“^”作为子分隔符,并仅保留该子分隔符的第一个值。

输出结果应为:

`a|b|d|e|g`

有没有一种简单的SQL函数可以实现这个功能?

你想使用哪种 SQL?无论如何,你可以简单地用空格替换 ^ 和其后的字符,因为你总是取第一个。 - Mihai-Daniel Virna
请指定您的关系型数据库管理系统(RDBMS)(Firebird/Teradata/MariaDB/...)。您的数据是否包含类似于a|ab^cd^ef|e^da的数据? - Lukasz Szozda
我正在使用SQL Server 2005,是的,它可以包含像a|b^c^d^e|f|g这样的值,我想输出a|b|f|g。基本上保留^之前的任何内容,并且删除下一个管道符号之前的所有内容。 - kunkel1
3个回答

3

另一种选择是使用 CHARINDEXREPLACESUBSTRING

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

@kunkel1,很抱歉告诉你,在最后一个脱字符号后面没有管道符时,这是一个无限循环。 - shawnt00
@shawnt00 在阅读了你的回答后,我进行了测试并编辑了我的回答。不过我必须承认,你的解决方案可能更好。我已经为你的回答点赞了。 - Zohar Peled
很酷。谢谢你的投票。我只是觉得回答被接受的速度总是很快,这让人感到有趣。没有恶意,但我怀疑声望在选择时经常影响OPs。还有最快的方式是放下答案并继续前进。 - shawnt00
2
@shawnt00:“我怀疑声望常常会影响到提问者。” 嗯,是的 ;-)。总的来说,投票者也是如此。这是在除了用户个人资料页面以外的任何地方列出声望的主要缺点之一。它使得获得隐含信任变得太容易,以至于有时候投票者甚至不费心检查答案就会点赞(尽管我并不意味着这个答案不应该得到任何票数,我只是指出了我注意到的一种行为)。 - Solomon Rutzky
1
我非常感谢所有的帮助。我根据哪个答案能够在我的应用程序中插入并使其工作(考虑到我有限的SQL知识),选择了最佳答案。我无法让其他两个答案工作(很可能是我的问题)。感谢您跟进修改。我的测试值没有出现这种情况,但如果不进行更正可能会出现问题,所以我进行了更正,现在一切看起来都很好。 :) - kunkel1
显示剩余3条评论

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

首先按照|分隔值,然后提取第一个值并将结果连接起来以获得结果。

试试这个方法

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


你假设这些值将是单个字符。 - shawnt00
如果原字符串是|xb^dfg|b|f^df|,那么这个答案会返回 |x|b|f|,而不是 |xb|b|f|... - Zohar Peled
@shawnt00 - 是的,因为样本数据的原因,现在已经更新了,请检查。 - Pரதீப்
@ZoharPeled - 我更新了我的回答 - Pரதீப்

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接