Leftrimming Zero使用SQL,其中包含字符串中的字符

时间:2017-02-21 12:38:57

标签: sql function tsql stored-procedures

我需要编写一个函数来删除varchar列中的所有前导零。例如:0300必须变为300,A0300必须变为A300。第一个是退出简单,但我不能让第二个工作(A0300-> A300)。有人能指出我正确的方向吗?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

做一个案例并使用LIKE' [0-9]' /不喜欢' [0-9]'找到正确的分裂点 - 假设知道字符串的最大长度,以便您可以根据需要准备尽可能多的案例。 您找到正确的数字开头的正确字符编号,并将正确的部分转换为INT以消除前导0,然后将结果转换为VARCHAR以与您的前导字母重新聚合。

会产生如下内容: 选择 左边的情况(列名,1)不喜欢' [0-9]' AND SUBSTRING(columnname,2,1)LIKE' [0-9]'那么左(列名,1)+ CAST(CAST(SUBSTRING(2,(LEN(列名)-2))AS INT)AS VARCHAR(25)) 左边(列名,2)不喜欢' [0-9]' AND SUBSTRING(列名,3,1).... 结束

如果您不确定前导/尾随空格,则应使用LTRIM(RTRIM(列名))修剪空格,因为我们正在计算可能更可靠的字符数。

答案 2 :(得分:0)

下面的恶化代码演示了一种方法,用每个简单的状态机遍历字符串,并解析 evil 零。要查看内部发生的情况,您可以在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