복붙노트

[SQL] SQL 서버에서 앞의 0을 트리밍을위한 더 나은 방법?

SQL

SQL 서버에서 앞의 0을 트리밍을위한 더 나은 방법?

나는 몇 시간 동안이를 사용하고있다 :

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 Server 2005에서 UDF의 성능 문제를 많이 발견했습니다.

해결법

  1. ==============================

    1.

    SUBSTRING(str_col, PATINDEX('%[^0]%', str_col+'.'), LEN(str_col))
    
  2. ==============================

    2.왜 그냥 다시 VARCHAR에 정수 값을 캐스팅하지?

    왜 그냥 다시 VARCHAR에 정수 값을 캐스팅하지?

    SELECT  CAST(CAST('000000000' AS INTEGER) AS VARCHAR)
    
    --------
           0
    
  3. ==============================

    3.모든 제로의 (또는 단일 영)이있는 경우 여기에 다른 대답은 고려하지합니다. 일부는 항상 공백으로 남아 가정 할 때 잘못 인 제로로 빈 문자열을 기본. 원래의 질문을 다시 읽기. 질문자가 원하는 것을이 답변.

    모든 제로의 (또는 단일 영)이있는 경우 여기에 다른 대답은 고려하지합니다. 일부는 항상 공백으로 남아 가정 할 때 잘못 인 제로로 빈 문자열을 기본. 원래의 질문을 다시 읽기. 질문자가 원하는 것을이 답변.

    --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"
    
    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이야 사용하면 완벽하게 괜찮습니다. 나는 우리의 제 3 자 데이터베이스와 같은 문제가 있습니다. 알파 - 숫자 필드와 함께 많은 사람들이 선행 공백없이 댕 인간에 입력됩니다! 이 차종은없는 최고의-0을 정리 없이는 불가능 합류했다.

    대신 선도-0을 제거, 당신은 당신이 당신의 조인을 수행 할 때 단지 선도 - 제로로 손질-값을 패딩 고려할 수 있습니다. 더 나은 아직, 다음, 맨 앞에 0을 추가하여 인덱스를 재 구축하여 테이블에서 데이터를 정리. 나는이 빠르고 덜 복잡한 방법이 될 것이라고 생각합니다.

    SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF(' 0A10  ', ''))), 10)--0000000A10
    SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF('', ''))), 10)--NULL --When Blank.
    
  4. ==============================

    4.대신 공간 일반적으로 열의 텍스트에 있지해야 '희귀'공백 문자로 0의 교체. 라인 피드는 아마 이런 열의 좋은 충분하다. 그런 다음에서는 LTrim 일반적으로 할 수있는 다시 공의와 특수 문자를 대체합니다.

    대신 공간 일반적으로 열의 텍스트에 있지해야 '희귀'공백 문자로 0의 교체. 라인 피드는 아마 이런 열의 좋은 충분하다. 그런 다음에서는 LTrim 일반적으로 할 수있는 다시 공의와 특수 문자를 대체합니다.

  5. ==============================

    5.다음은 문자열이 제로의 전체 구성되는 경우 '0'을 반환합니다 :

    다음은 문자열이 제로의 전체 구성되는 경우 '0'을 반환합니다 :

    CASE WHEN SUBSTRING(str_col, PATINDEX('%[^0]%', str_col+'.'), LEN(str_col)) = '' THEN '0' ELSE SUBSTRING(str_col, PATINDEX('%[^0]%', str_col+'.'), LEN(str_col)) END AS str_col
    
  6. ==============================

    6.이것은 좋은 기능을합니다 ....

    이것은 좋은 기능을합니다 ....

    DROP FUNCTION [dbo].[FN_StripLeading]
    GO
    CREATE FUNCTION [dbo].[FN_StripLeading] (@string VarChar(128), @stripChar VarChar(1))
    RETURNS VarChar(128)
    AS
    BEGIN
    -- http://stackoverflow.com/questions/662383/better-techniques-for-trimming-leading-zeros-in-sql-server
        DECLARE @retVal VarChar(128),
                @pattern varChar(10)
        SELECT @pattern = '%[^'+@stripChar+']%'
        SELECT @retVal = CASE WHEN SUBSTRING(@string, PATINDEX(@pattern, @string+'.'), LEN(@string)) = '' THEN @stripChar ELSE SUBSTRING(@string, PATINDEX(@pattern, @string+'.'), LEN(@string)) END
        RETURN (@retVal)
    END
    GO
    GRANT EXECUTE ON [dbo].[FN_StripLeading] TO PUBLIC
    
  7. ==============================

    7.문자열이 숫자 인 경우 캐스트 (int로서 값)은 항상 작동합니다

    문자열이 숫자 인 경우 캐스트 (int로서 값)은 항상 작동합니다

  8. ==============================

    8.이것의 나의 버전은 더이 다른 경우를 보장하기에 추가 조금으로, 아르보의 작품의 적응이다.

    이것의 나의 버전은 더이 다른 경우를 보장하기에 추가 조금으로, 아르보의 작품의 적응이다.

    우리는 모두 0이있는 경우 1) 우리는 숫자 0을 반환해야합니다.

    우리는 빈이있는 경우 2), 우리는 여전히 빈 문자를 반환해야합니다.

    CASE 
        WHEN PATINDEX('%[^0]%', str_col + '.') > LEN(str_col) THEN RIGHT(str_col, 1) 
        ELSE SUBSTRING(str_col, PATINDEX('%[^0]%', str_col + '.'), LEN(str_col))
     END
    
  9. ==============================

    9.

    SELECT CAST(CAST('000000000' AS INTEGER) AS VARCHAR)
    

    이것은 INT로 변환 할 수있는 문자열의 길이에 제한이

  10. ==============================

    10.당신이 눈송이 SQL을 사용하는 경우이를 사용할 수 있습니다 :

    당신이 눈송이 SQL을 사용하는 경우이를 사용할 수 있습니다 :

    ltrim(str_col,'0')
    

    LTRIM 함수는 왼쪽에서 문자의 지정된 세트의 모든 인스턴스를 제거한다.

    그래서 LTRIM (str_col, '0') '00000008A'에 '는 8A를'반환

    그리고 ( '0을.'str_col를) RTRIM '$ 125'에 '$ 125'반환

  11. ==============================

    11.

      SUBSTRING(str_col, IIF(LEN(str_col) > 0, PATINDEX('%[^0]%', LEFT(str_col, LEN(str_col) - 1) + '.'), 0), LEN(str_col))
    

    심지어는 '0', '00'등으로 잘 작동합니다.

  12. ==============================

    12.

    replace(ltrim(replace(Fieldname.TableName, '0', '')), '', '0')
    

    토마스 G에서 제안은 우리의 필요를 위해 일했다.

    우리의 경우 필드는 이미 문자열이었고, 단지 앞의 0은 손질 할 필요가 있었다. 대부분은 모든 숫자입니다하지만 이전 INT 변환이 충돌 할 수 있도록 가끔 문자가 있습니다.

  13. ==============================

    13.당신이 INT로 변환 할 수없는 경우는 null을 처리 할 수 ​​있기 때문에, 나는 논리 아래이 선호     IFNULL (필드, LTRIM (필드, '0'))

    당신이 INT로 변환 할 수없는 경우는 null을 처리 할 수 ​​있기 때문에, 나는 논리 아래이 선호     IFNULL (필드, LTRIM (필드, '0'))

  14. ==============================

    14.이 시도:

    이 시도:

    replace(ltrim(replace(@str, '0', ' ')), ' ', '0')
    
  15. from https://stackoverflow.com/questions/662383/better-techniques-for-trimming-leading-zeros-in-sql-server by cc-by-sa and MIT license