2017-02-21 129 views
0

我需要编写一个函数,从varchar列中删除所有前导零。例如:0300必须变为300,A0300必须变成A300。第一个退出容易,但我不能得到第二个工作(A0300-> A300)。任何人都可以将我指向正确的方向吗?Leftrimming Zero与字符串中包含的字符与字符

+0

总是以字母'A'开头还是它可能是字符串的不同长度? –

+0

它可以是任何字符或多个字母,如ABC0150 – ImperialBert

+0

所以''zer0''应该变成''zer''和''0''应该变成'''''? – HABO

回答

1
WITH test AS 
(
    SELECT 'A0300' AS code 
    UNION 
    SELECT '0300' 
), 
strip AS (
SELECT code, SUBSTRING(code, PATINDEX('%[0-9]%', code), LEN(code)) AS number 
from test 
) 

select REPLACE(code, number, CAST(number as INT)) 
FROM strip 
0

在旧版本,其中PATINDEX不起作用,或者如果PATINDEX太慢:

做的情况下,并使用LIKE '[0-9]'/ NOT LIKE '[0-9]'找到正确的分裂点 - 假设知道您的字符串的最大长度,以便您可以根据需要准备多个案例。 您可以在数字开头找到正确的字符编号,并将右边的部分作为INT进行转义以消除前导0,然后将结果作为VARCHAR进行转换,以重新汇总您的前导字母。

会制造类似如下: 选择 CASE WHEN LEFT(列名,1)NOT LIKE '[0-9]' 和substring(列名,2,1)LIKE '[0-9]' 然后离开( (列名,2)(LEN(columnname)-2))AS INT)AS VARCHAR(25)) 当左(列名,2)不像'[0-9]'和底层(columnname,3,1).... END

如果您不确定前导/尾随空格,您应该用LTRIM(RTRIM(columnname))修剪空格,因为我们要计算字符可能更可靠。

0

下面的溃烂代码演示了一种方式,用一个平凡的状态机遍历字符串,并解析出邪恶的零。要查看内部发生了什么,可以在CTE之后切换select

-- Sample data. 
declare @Samples as Table (SampleId Int Identity, Sample VarChar(100)); 
insert into @Samples (Sample) values 
    ('0300'), ('A0300'), ('zer0'), ('0'), ('000'), ('00000Q050098'); 
select * from @Samples; 

-- Fiendish thingy. 
declare @False as Bit = 0, @True as Bit = 1; 
with 
    Characters as (
    select SampleId, Sample, 1 as Position, Substring(Sample, 1, 1) as Character, 
     case when Substring(Sample, 1, 1) = '0' then @True else @False end as IsZero, 
     case when Substring(Sample, 1, 1) = '0' then @True else @False end as FirstZeroes 
     from @Samples 
    union all 
    select SampleId, Sample, Position + 1, Substring(Sample, Position + 1, 1), 
     case when Substring(Sample, Position + 1, 1) = '0' then @True else @False end, 
     case 
     when FirstZeroes is NULL then NULL -- We're done with this string. 
     when FirstZeroes = @True and Substring(Sample, Position + 1, 1) <> '0' then NULL -- We just finished with this string. 
     when Substring(Sample, Position + 1, 1) = '0' then @True -- We're (still) going with this string. 
     else @False end 
     from Characters 
     where Position < Len(Sample)) 
-- select * from Characters order by SampleId, Position; -- Use this statement to see the intermediate results. 
    select C.SampleId, C.Sample, 
    Coalesce(Stuff((select Character from Characters where SampleId = C.SampleId and (FirstZeroes = 0 or FirstZeroes is NULL) order by Position for XML path(''), type).value('.[1]', 'VarChar(max)'), 1, 0, ''), '') as DeZeroed 
    from Characters as C 
    group by SampleId, Sample