如何在两个字符之间获取字符串

时间:2014-01-08 00:11:00

标签: sql sql-server substring charindex

我需要在 - 和 - 之间获取字符串,即GigabitEthernet1 / 0/1

CW-3D13-SW1 - GigabitEthernet1/0/1 · Uplink to 1K5-Core1
CW-3D13-SW1 - FastEthernet1/0/43 · PHSA-MPAACT-3D13/16 - Cisco 2811 Fa 0/0
c&w-internet-sw-ACB - GigabitEthernet1/0/24 · MPAACT PNG/UBC School of Medicine
c&w-internet-sw-ACB - GigabitEthernet1/0/25 - Int-Link-CW-BCCA-Oak-St

我可以使用以下

SUBSTRING(Caption, CHARINDEX(' - ', Caption) + 3, CHARINDEX(' · ', Caption) - CHARINDEX('- ', Caption) + LEN(' · ') - 3)

它会给我我想要的东西,但是有一些实例用·替换 - 。例如:

c&w-internet-sw-ACB - GigabitEthernet1/0/25 - Int-Link-CW-BCCA-Oak-St

这会打破我的疑问。 有没有办法满足两者 - 和

感谢

更新 - 是否可以添加其他条件?当字符串如下:

VPN 3030  - PCI Fast Ethernet  

最后没有 - 或者。在这种情况下,我只想要在 -

之后发生的事情

3 个答案:

答案 0 :(得分:4)

试试这个

Declare @LeftMarker varchar(3)
Declare @RightMarker varchar(3)
    Set @LeftMarker = ' - '     --<--- Replace this with your choice
    Set @RightMarker = ' · '    --<--- Replace this with your choice

Declare @LMarkerLen int
    Set @LMarkerLen = LEN(@LeftMarker)

SELECT  Case When CHARINDEX(@RightMarker, Caption) > 0 Then
            SUBSTRING(Caption, CHARINDEX(@LeftMarker, Caption) + @LMarkerLen, CHARINDEX(@RightMarker, Caption) - (CHARINDEX(@LeftMarker, Caption) + @LMarkerLen))
        Else
            SUBSTRING(Caption, CHARINDEX(@LeftMarker, Caption) + @LMarkerLen, CHARINDEX(@LeftMarker, Caption, CHARINDEX(@LeftMarker, Caption) + @LMarkerLen) - (CHARINDEX(@LeftMarker, Caption) + @LMarkerLen))
        End AS Result
FROM .......

答案 1 :(得分:0)

这是ugly as hell,但我认为它可以满足您的需求。

SELECT 
  SUBSTRING(Caption, 
            CHARINDEX(' - ', Caption) + 3, 
            CHARINDEX(' · ', Caption) - CHARINDEX('- ', Caption) + LEN(' · ') - 3) 
FROM
  Foo
WHERE
  CHARINDEX(' · ', Caption) > 0
UNION
SELECT
SUBSTRING(
  REVERSE(
  SUBSTRING(REVERSE(Caption), 
            CHARINDEX(' - ', REVERSE(Caption)) + 3,
            LEN(Caption))
  ),
  CHARINDEX(' - ', REVERSE(
  SUBSTRING(REVERSE(Caption), 
            CHARINDEX(' - ', REVERSE(Caption)) + 3,
            LEN(Caption))
  )) + 3,
  LEN(Caption))
FROM
  Foo
WHERE
  CHARINDEX(' · ', Caption) = 0

简要说明一下,对于点不是分隔符/分隔符的那些,反转标题并从“ - ”的第一个实例一直到结尾获取子字符串。反转此操作的结果,将其返回到原来的顺序,并再次从第一个“ - ”实例获取子字符串到最后。

答案 2 :(得分:0)

我为此创建了一个min函数。

create function dbo.fnMin( @P1 int, @P2 int)
    returns int
as
begin
    return case when @P1 > @P2 then coalesce(@P2,@P1) else coalesce(@P1,@P2) end;
end
go

它只返回两个值中较小的一个。然后,您可以使用它来执行 RIGHT ,然后使用 LEFT 。实际上,你可以将它放在一个select语句中,但在我看来,将它拆分为我所做的更容易理解。试一试......希望它有效!

select coalesce(left(SubStr, dbo.fnMin(nullif(charindex(' - ',SubStr),0),nullif(charindex(' · ',SubStr),0)) ),SubStr)
from (
    select right([Caption],len([Caption])-(dbo.fnMin(nullif(charindex(' - ',[Caption]),0),nullif(charindex(' · ',[Caption]),0)))-3) as SubStr
    from <YourTableName>
) t

内部选择语句获取第一个“ - ”或“·”的所有值 RIGHT 。然后外部选择将获得第二个“ - ”或“·”的所有 LEFT


我已经编辑了我的代码以便没有第二个“ - ”或“·”

编辑:我不能使用sqlfiddle,因为这个解决方案需要一个函数......但这是我在沙箱环境中运行的...

create table dbo.Interfaces (Caption varchar(1000))
go
insert into dbo.Interfaces
values
('CW-3D13-SW1 - GigabitEthernet1/0/1 · Uplink to 1K5-Core1'),
('CW-3D13-SW1 - FastEthernet1/0/43 · PHSA-MPAACT-3D13/16 - Cisco 2811 Fa 0/0'),
('c&w-internet-sw-ACB - GigabitEthernet1/0/24 · MPAACT PNG/UBC School of Medicine'),
('c&w-internet-sw-ACB - GigabitEthernet1/0/25 - Int-Link-CW-BCCA-Oak-St'),
('VPN 3030  - PCI Fast Ethernet')
go

create function dbo.fnMin( @P1 int, @P2 int)
    returns int
as
begin
    return case when @P1 > @P2 then coalesce(@P2,@P1) else coalesce(@P1,@P2) end;
end
go

select coalesce(left(SubStr, dbo.fnMin(nullif(charindex(' - ',SubStr),0),nullif(charindex(' · ',SubStr),0)) ),SubStr)
from (
    select right([Caption],len([Caption])-(dbo.fnMin(nullif(charindex(' - ',[Caption]),0),nullif(charindex(' · ',[Caption]),0)))-3) as SubStr
    from dbo.Interfaces
) t
go

这是结果......

igabitEthernet1/0/1 
astEthernet1/0/43 
igabitEthernet1/0/24 
igabitEthernet1/0/25 
CI Fast Ethernet

(5 row(s) affected)

如果你无法从这段代码中弄明白......是时候先找书了。 ;)