我使用this已经有一段时间了:
SUBSTRING(str_col, PATINDEX('%[^0]%', str_col), LEN(str_col))
然而,最近我发现了一个问题,所有"0“字符的列,比如”00000000“,因为它永远找不到匹配的非”0“字符。
我见过的另一种技术是使用TRIM
REPLACE(LTRIM(REPLACE(str_col, '0', ' ')), ' ', '0')
如果有嵌入的空格,这就会有问题,因为当空格变成“0”时,它们就会变成“0”。
我正在尝试避免标量UDF。我在SQL Server2005中发现了许多UDF的性能问题。
发布于 2009-03-19 14:32:58
SUBSTRING(str_col, PATINDEX('%[^0]%', str_col+'.'), LEN(str_col))
发布于 2009-03-19 14:21:05
为什么不直接将值转换为INTEGER
,然后再返回给VARCHAR
SELECT CAST(CAST('000000000' AS INTEGER) AS VARCHAR)
--------
0
发布于 2014-02-16 07:25:19
如果你有全零(甚至是一个零),这里的其他答案就不会被考虑在内。
有些总是将空字符串默认为零,这是错误的,因为它应该保留为空。
重读原来的问题。这就回答了提问者想要的。
解决方案#1:
--This example uses both Leading and Trailing zero's.
--Avoid losing those Trailing zero's and converting embedded spaces into more zeros.
--I added a non-whitespace character ("_") to retain trailing zero's after calling Replace().
--Simply remove the RTrim() function call if you want to preserve trailing spaces.
--If you treat zero's and empty-strings as the same thing for your application,
-- then you may skip the Case-Statement entirely and just use CN.CleanNumber .
DECLARE @WackadooNumber VarChar(50) = ' 0 0123ABC D0 '--'000'--
SELECT WN.WackadooNumber, CN.CleanNumber,
(CASE WHEN WN.WackadooNumber LIKE '%0%' AND CN.CleanNumber = '' THEN '0' ELSE CN.CleanNumber END)[AllowZero]
FROM (SELECT @WackadooNumber[WackadooNumber]) AS WN
OUTER APPLY (SELECT RTRIM(RIGHT(WN.WackadooNumber, LEN(LTRIM(REPLACE(WN.WackadooNumber + '_', '0', ' '))) - 1))[CleanNumber]) AS CN
--Result: "123ABC D0"
解决方案#2 (包含示例数据):
SELECT O.Type, O.Value, Parsed.Value[WrongValue],
(CASE WHEN CHARINDEX('0', T.Value) > 0--If there's at least one zero.
AND LEN(Parsed.Value) = 0--And the trimmed length is zero.
THEN '0' ELSE Parsed.Value END)[FinalValue],
(CASE WHEN CHARINDEX('0', T.Value) > 0--If there's at least one zero.
AND LEN(Parsed.TrimmedValue) = 0--And the trimmed length is zero.
THEN '0' ELSE LTRIM(RTRIM(Parsed.TrimmedValue)) END)[FinalTrimmedValue]
FROM
(
VALUES ('Null', NULL), ('EmptyString', ''),
('Zero', '0'), ('Zero', '0000'), ('Zero', '000.000'),
('Spaces', ' 0 A B C '), ('Number', '000123'),
('AlphaNum', '000ABC123'), ('NoZero', 'NoZerosHere')
) AS O(Type, Value)--O is for Original.
CROSS APPLY
( --This Step is Optional. Use if you also want to remove leading spaces.
SELECT LTRIM(RTRIM(O.Value))[Value]
) AS T--T is for Trimmed.
CROSS APPLY
( --From @CadeRoux's Post.
SELECT SUBSTRING(O.Value, PATINDEX('%[^0]%', O.Value + '.'), LEN(O.Value))[Value],
SUBSTRING(T.Value, PATINDEX('%[^0]%', T.Value + '.'), LEN(T.Value))[TrimmedValue]
) AS Parsed
结果:
摘要:
您可以使用上面的代码一次性删除前导零。
如果你打算经常重用它,那么把它放在一个内联表值函数(ITVF)中。
您对UDF的性能问题的担忧是可以理解的。
然而,这个问题只适用于全标量函数和多语句表函数。
使用ITVF是非常好的。
我们的第三方数据库也有同样的问题。
有了字母-数字字段,许多都是在没有前导空格的情况下输入的,该死的人类!
这使得在不清除丢失的前导零的情况下连接是不可能的。
结论:
与删除前导零不同,您可能需要考虑在进行连接时只用前导零填充修剪后的值。
更好的做法是,通过添加前导零来清理表中的数据,然后重新构建索引。
我认为这会更快,更简单。
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF(' 0A10 ', ''))), 10)--0000000A10
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF('', ''))), 10)--NULL --When Blank.
https://stackoverflow.com/questions/662383
复制相似问题