如何在SQL Server中第二次到最后一次出现字符串后替换值?

时间:2018-03-20 22:54:07

标签: sql sql-server

declare @test varchar(50) = 'F-1084-002-04-009'

我需要将最后两个破折号内的值替换为“00”

所以它应该是这样的:

F-1084-002-00-009

我很难找到最简单的方法。

5 个答案:

答案 0 :(得分:1)

如果格式始终相同,则可以执行此操作:

 select stuff('F-1084-002-04-009', 12, 2, '00')

答案 1 :(得分:0)

这样的事情:

select *,
    charindex('-', reverse(v), 0) Last,
    charindex('-', reverse(v), charindex('-', reverse(v), 0)+1) Second_Last,
    left(v, len(v)-(charindex('-', reverse(v), charindex('-', reverse(v), 0)+1)))
        + '-00'
        +right(v, charindex('-', reverse(v), 0))
from t

答案 2 :(得分:0)

我发布这个作为一个单独的答案,因为虽然我很满意它,但它有点不同寻常。然而,即使你绝对没有假设每组有多少组或每组中有多少个字符,它也非常强大。

前两个表变量只是设置数据。我使用了你的测试例子并添加了我自己的三分之一。我还创建了一个小型自动递增计数表。如果你还没有,我建议在你的数据库中保留其中一个。

declare @src table (val)
insert into @src (Val)
values
    ('F-0-001-99-003'),
    ('F-1084-002-04-009'),
    ('FF-1-02-345-9')

declare @tally table (idx)
insert into @tally (idx)
select top 100 row_number() over (order by (select null)) - 1 -- 0 based
from sys.all_objects

现在我们认真开始工作。我使用了一种技巧,我通过编写SQL逗号分隔字符串分割器来快速获取字符串中所有连字符的索引。我在这里感兴趣的是倒数第二个连字符(它开始我们想要替换的部分)和最后一个连字符(表示它的结束)。我加1,因为计算机就是这样。

现在我需要获得具有最高索引和第二高索引的行。我用row_number和group by来解决这个问题,但我怀疑还有其他方法可以解决这个问题。

因此,对于最终选择,我们有要替换的slug的起始索引,结束索引以及它的长度(为了简洁起见,我刚刚将其保存为附加列。

点,使用stuff的原始解决方案有效。

;with hyphenIndexes as
(
    select 
        RID = row_number() over (partition by s.Val order by idx desc),
        Val, 
        Idx = Idx + 1
    from @src s
    inner join @tally t
        on t.idx <= len(val)
    where substring(val, idx, 1) = '-'
), almostDone as
(
    select 
        Val,
        StartIndex = max(iif(RID = 2, idx, null)),
        EndIndex = max(Idx),
        SlugLength = max(Idx) - max(iif(RID = 2, idx, null)) - 1
    from hyphenIndexes
    group by Val
)
select
    OriginalString = val,
    ReplacedString = stuff
        (
            Val, 
            StartIndex, 
            SlugLength,
            replicate('0', SlugLength)
        ) 
from almostDone

我应该注意到它已经很晚了,而且我的大脑非常油炸,所以可能有办法让它更简洁。为了清晰起见,我也把事情搞得一团糟。我也从这个角度来看待它,因为琴弦可能都是严厉的,但它仍然有效。但是,如果您能够对组的数量或每组的字符数做出任何假设,我怀疑您可以跳过我在这里完成的几个步骤。

答案 3 :(得分:0)

 - Simple way is to Use Substring to find what you want to Replace.And
   use Replace Function to Replace it.

DECLARE @test NVARCHAR(50) = 'F-1084-002-04-009',
       @Replce NVARCHAR(3),
       @Value NVARCHAR(10)='00'

       SELECT @Replce=SUBSTRING(@test,12,2)

       SELECT REPLACE(@test,@Replce,@Value)

答案 4 :(得分:0)

这适用于倒数第二个元素中的可变长度字符串:

use tempdb

create table t
(
    v varchar(90)
)

insert t (v)
values  ('F-1084-002-04-009'),
        ('g-68236-6514652145-99-8127638176321637'),
        ('F-1084-002-0456-009')

select *,
    stuff(
        v,
        len(v) - (charindex('-', reverse(v), charindex('-', reverse(v), 0)+1) - 2),
        (charindex('-', reverse(v), charindex('-', reverse(v), 0)+1) - charindex('-', reverse(v), 0))-1,
        replicate('0', charindex('-', reverse(v), charindex('-', reverse(v), 0)+1) - charindex('-', reverse(v), 0) - 1)
    ) [Stuff]
from t