【问题标题】:SQL Remove string between two charactersSQL删除两个字符之间的字符串
【发布时间】:2016-07-01 05:30:47
【问题描述】:

我有一个这样的字符串:

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

我想保持管道定界,但删除胡萝卜子定界,只保留该子定界符的第一个值。

输出结果是:

`a|b|d|e|g`

有没有办法用一个简单的 SQL 函数来做到这一点?

【问题讨论】:

  • 你想使用哪个 sql?无论如何,你可以简单地用空格替换 ^ 和后面的字符,因为你总是取第一个。
  • 指定您的 RDBMS (Firebird/Teradata/MariaDB/...)。您的数据是否包含a|ab^cd^ef|e^da 之类的数据?
  • 我用的是sql server 2005,是的,它可以包含a|b^c^d^e|f|g之类的值,我想输出a|b|f|g。基本上保留 ^ 之前的所有内容,并在下一个管道之前摆脱所有内容。

标签: sql sql-server tsql sql-server-2005


【解决方案1】:

另一个选项,使用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 “我怀疑声誉经常影响 OP”:嗯,是的 ;-)。好吧,一般的选民。这是在除用户个人资料页面之外的任何内容上列出代表的主要缺点之一。这使得获得隐含信任变得太容易了,以至于有时选民在投票之前甚至都懒得检查答案(尽管我并不是暗示这个答案不应该得到任何选票,我只是指出我的一种行为已经注意到了)。
  • 感谢所有帮助。我根据我有限的 SQL 知识可以插入并在我的应用程序中使用哪个答案来选择最佳答案。我无法让其他两个工作(很可能是我的错)。感谢您跟进修改。我的测试值没有这种情况,但留下它可能会很糟糕,所以我进行了更正,一切看起来都很好。 :)
【解决方案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;

需要注意没有最终管道分隔符的字符串尾随。你可以看到我已经处理好了。

【讨论】:

    【解决方案3】:

    先拆分|分隔的值,然后提取第一个值并将结果串联回来得到结果

    试试这个

    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

    【讨论】:

    • 您假设这些值将是单个字符。
    • 如果原始字符串是|xb^dfg|b|f^df|怎么办?这个答案将返回|x|b|f|,而不是|xb|b|f|...
    • @shawnt00 - 是的,因为样本数据,现在检查更新
    • @ZoharPeled - 更新了我的答案
    猜你喜欢
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 2019-10-27
    • 2017-10-24
    • 2018-11-25
    相关资源
    最近更新 更多