繁体   English   中英

在子字符串中使用charindex来修剪字符串

[英]using charindex in a substring to trim a string

有一个列name ,我想用它来创建一个新列。 例:

name
asd_abceur1mz_a
asd_fxasdrasdusd3mz_a
asd_abceur10yz_a
asd_fxasdrasdusd15yz_a

列的长度不固定所以我假设我必须使用charindex来获得一个可以修剪的参考点。

我想要的是:最后总是有z_a ,我需要在z_a的左侧部分放置一个单独的列,如下所示:

nameNew
eur1m
usd3m
eur10y
usd15y

问题是数字(在这个例子中为1,3,10,15)有1位或2位数。 我需要从namenameNew提取信息。

之后,我想更容易阅读并输出如下:

eur_1m
usd_3m
eur_10y
usd_15y

我尝试使用substring和charindex的组合,但到目前为止还没有成功。

SELECT  *
      , SUBSTRING(name, 1, ( CHARINDEX('z_a', NAME) - 1 )) AS nameNew
FROM    myTable

这是第一步,修剪字符串,第二步(使其更容易阅读)我不知道如何定位数字并放置_ 任何帮助,将不胜感激。 使用sql server 2012

编辑:

首先感谢您的时间和解决方案。 但是你的查询或多或少,即使它们工作1或2位数也有同样的问题。 考虑这种情况:

name
ab_dertEUR03EUR10YZ_A

如果eur是字符串中的两倍,那我怎么能消除这个呢? 很抱歉没有在我原来的帖子中包含这个,但我忘了这种情况是可能的,现在这是一个问题。

编辑:

在此示例中测试您的查询: http//www.sqlfiddle.com/#!3/21610/1

请注意 ,最后它可以是1或2位数字和字母y或m的任意组合。

例如: ab_rtgtEUR03EUR2YZ_Aab_rtgtEUR03EUR2mZ_Aab_rtgtEUR03EUR20YZ_Aab_rtgtEUR03EUR20mZ_A

一些测试值:( ('ex_CHFCHF01CHF10YZ_A'), ('ab_rtgtEUR03EUR2YZ_A'), ('RON_asdRON2MZ_A'), ('tg_USDUSD04USD5YZ_A');

我对你的疑问的理解是他们执行了类似的事情(至少他们应该)

ex_CHFCHF01CHF10YZ_A -> ex_CHFCHF01CHF10Y -> Y01FHC10FHCFHC -> Y01FHC -> CHF01Y -> CHF_01Y
RON_asdRON2MZ_A      ->  RON_asdRON2M     -> M2NORdsa_ron   -> M2NOR  -> RON2M  -> RON_2M

这适用于一个或两个数字:

stuff(case
        when name like '%[0-9][0-9]_z[_]a'
          then left(right(name, 9), 6)
        when name like '%[0-9]_z[_]a'
          then left(right(name, 8), 5)
      end, 4, 0, '_')

您可以使用substringreversecharindex的组合。

SQL小提琴

select substring(namenew,1,3) + '_' + substring(namenew, 4, len(namenew))
from (
select 
case when name like '%[0-9][0-9]_z[_]a' then 
reverse(substring(reverse(name), charindex('a_z',reverse(name)) + 3, 6)) 
     when name like '%[0-9]_z[_]a' then 
reverse(substring(reverse(name), charindex('a_z',reverse(name)) + 3, 5)) 
end as namenew
from myTable 
) t

试试这样:

declare @tbl TABLE(name VARCHAR(100));
insert into @tbl VALUES
 ('asd_abceur1mz_a')
,('asd_fxasdrasdusd3mz_a')
,('asd_abceur10yz_a')
,('asd_fxasdrasdusd15yz_a')
,('ab_dertEUR03EUR10YZ_A');

WITH CutOfThreeAtTheEnd AS
(
    SELECT LEFT(name,LEN(name)-3) AS nameNew
    FROM @tbl
)
,Max6CharsFromEnd AS
(
    SELECT RIGHT(nameNew,6) AS nameNew
    FROM CutOfThreeAtTheEnd
)
SELECT nameNew  
      ,FirstNumber.Position
      ,Parts.*
      ,Parts.FrontPart + '_' + Parts.BackPart AS FinalString
FROM Max6CharsFromEnd 
CROSS APPLY
(
    SELECT MIN(x) 
    FROM
    (
              SELECT CHARINDEX('0',nameNew,1) AS x
        UNION SELECT CHARINDEX('1',nameNew,1)
        UNION SELECT CHARINDEX('2',nameNew,1)
        UNION SELECT CHARINDEX('3',nameNew,1)
        UNION SELECT CHARINDEX('4',nameNew,1)
        UNION SELECT CHARINDEX('5',nameNew,1)
        UNION SELECT CHARINDEX('6',nameNew,1)
        UNION SELECT CHARINDEX('7',nameNew,1)
        UNION SELECT CHARINDEX('8',nameNew,1)
        UNION SELECT CHARINDEX('9',nameNew,1)
    ) AS tbl
    WHERE x>0
) AS FirstNumber(Position)
CROSS APPLY(SELECT SUBSTRING(nameNew,FirstNumber.Position,1000) AS BackPart
                  ,SUBSTRING(nameNew,FirstNumber.Position-3,3) AS FrontPart) AS Parts

这是结果:

nameNew    Position BackPart    FrontPart   FinalString
ceur1m     5        1m          eur         eur_1m
dusd3m     5        3m          usd         usd_3m
eur10y     4        10y         eur         eur_10y
usd15y     4        15y         usd         usd_15y
EUR10Y     4        10Y         EUR         EUR_10Y

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM