Otras respuestas aquí para no tener en cuenta si tiene todo cero (o incluso un solo cero).
Algunos siempre predeterminan una cadena vacía a cero, lo cual es incorrecto cuando se supone que debe permanecer en blanco.
Vuelva a leer la pregunta original. Esto responde a lo que quiere el interrogador.
Solución # 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"
Solución # 2 (con datos de muestra):
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
Resultados:
Resumen:
Podrías usar lo que tengo arriba para una eliminación única de los ceros a la izquierda.
Si planea reutilizarlo mucho, colóquelo en una función de valor de tabla en línea (ITVF).
Sus preocupaciones sobre problemas de rendimiento con UDF son comprensibles.
Sin embargo, este problema solo se aplica a todas las funciones escalares y a las funciones de tabla de varias instrucciones.
Usar ITVF está perfectamente bien.
Tengo el mismo problema con nuestra base de datos de terceros.
¡Con los campos alfanuméricos se ingresan muchos sin los espacios iniciales, malditos humanos!
Esto hace que las uniones sean imposibles sin limpiar los ceros iniciales que faltan.
Conclusión:
En lugar de eliminar los ceros a la izquierda, puede considerar simplemente rellenar sus valores recortados con ceros a la izquierda cuando haga sus uniones.
Mejor aún, limpie sus datos en la tabla agregando ceros a la izquierda y luego reconstruyendo sus índices.
Creo que esto sería MUCHO más rápido y menos complejo.
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF(' 0A10 ', ''))), 10)--0000000A10
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF('', ''))), 10)--NULL --When Blank.