SQL Server 2008에서 앞에 오는 0으로 문자열을 채우면 길이는 3 자입니다.


398

SQL Server 2008 R2에서 처음 만들 때 최대 3 자 길이의 문자열이 있습니다.

선행 0으로 채우고 싶습니다. 원래 값이 '1'이면 새 값은 '001'입니다. 또는 원래 값이 '23'인 경우 새 값은 '023'입니다. 또는 원래 값이 '124'이면 새 값은 원래 값과 같습니다.

SQL Server 2008 R2를 사용하고 있습니다. T-SQL을 사용하여이 작업을 어떻게 수행합니까?



답변:


681

필드가 이미 문자열 인 경우 작동합니다

 SELECT RIGHT('000'+ISNULL(field,''),3)

null을 '000'으로 표시하려면

정수 일 수 있습니다-원하는 경우

 SELECT RIGHT('000'+CAST(field AS VARCHAR(3)),3)

질문에 필요한 것처럼이 대답은 길이 <= 3 인 경우에만 작동합니다. 더 큰 것을 원하면 문자열 상수와 두 정수 상수를 필요한 너비로 변경해야합니다. 예 :'0000' and VARCHAR(4)),4


8
나는 2 ~ 3 자 길이의 소수의 값을 가진 Char (6) 필드를 가지고 있었고 위의 내용은 저에게 효과적이지 않았습니다. '000000'+ ISNULL (FIELD, '') 주위에 RTRIM을 추가해야 작동했습니다.
— DWiener

3
Hogan 그래, 알았지 만 문자열이 얼마나 오래 작동하지 않더라도 이유를 알아 내기에는 너무 바쁘지만 CHAR (6) 필드가 RIGHT ( '000000 '+ ISNULL (field,' '), 6)은 작동하지 않지만 RIGHT (RTRIM ('000000 '+ ISNULL (field,' ')), 6)는 작동하지 않았습니다.
— DWiener

2
오, 이해합니다. 문자열로 인코딩 된 숫자 오른쪽에 공백이 있습니다.
— 호건

3
@dwiener char이 고정 길이 데이터 유형이기 때문에이 동작이 발생하므로 char (6)은 6자를 의미합니다. 실제 값이 6보다 작 으면 오른쪽에 공백으로 채워 지므로 제안 된 답변은 char (6)에 대해 잘못된 결과를 생성합니다.
— Giannis Paraskevopoulos

2
@Hogan, 그렇습니다.하지만이 질문은 "sql add Leading zeros"에 대한 Google 검색 결과 1 위이므로 많은 사람들 (sqlserver를 사용하지 않지만 google이 질문을하는 사람들)에게는 다른 데이터베이스에서 유용 할 수 있다고 생각합니다. 더 편리한 기능 lpad가 존재합니다. 어쨌든 고마워
— diralik

142

질문은 SQL Server 2008 R2에 대한 것이지만 누군가 누군가 2012 이상 버전으로 이것을 읽는 경우 FORMAT을 사용하면 훨씬 쉬워졌습니다 .

표준 숫자 형식 문자열 또는 사용자 지정 숫자 형식 문자열 을 형식 인수로 전달할 수 있습니다 ( 이 힌트에 대해 Vadim Ovchinnikov 에게 감사드립니다 ).

이 질문에 대해 예를 들어

DECLARE @myInt INT = 1;
-- One way using a standard numeric format string
PRINT FORMAT(@myInt,'D3');
-- Other way using a custom numeric format string
PRINT FORMAT(@myInt,'00#');

출력

001
001

2
입력 번호가 111 또는 11이면 어떻게됩니까?
— Hogan

6
1의 경우 001, 11의 경우 011, 111의 경우 111
— Géza

2
'00 # '대신'D3 '을 사용할 수 있습니다.
— Vadim Ovchinnikov

1
느린 허용 대답보다 더 있지만, 많은 양의 데이터와 작동하지 않는 경우 sooo를 훨씬 쉽게 상당히 것 같다
— 루트

2
비논리적 인 것처럼 보이지만 FORMAT은 varchar가 아닌 숫자 및 날짜 유형에서만 작동합니다.
— strattonn

120

안전한 방법 :

SELECT REPLACE(STR(n,3),' ','0')

이것은 '***'n <0 또는 n> 999에 대한 문자열 을 반환하는 이점이 있는데 , 이는 범위를 벗어난 입력을 나타내는 훌륭한 지표입니다. 여기에 나열된 다른 방법은 입력을 3 문자 하위 문자열로 자르면 자동으로 실패합니다.


10
젠장,이 페이지를 방문한 사람은이 페이지가 맨 위로 떠오르도록 도와야합니다!
— MarioDS

1
이 방법에주의하십시오. 표현식이 지정된 길이를 초과하면 문자열은 지정된 길이에 대해 **를 반환합니다. 예를 들어 str (n, 10)의 경우 n = 1000000000이면 별 (*)이 나타납니다.
— 언 바운드

나는 이것이 어떻게 작동하는지 모르지만 놀랍고 간단합니다.
— RaRdEvA

1
이것에주의해서 문자열은 그것을 끊습니다 (그리고 OP는 "문자열 패딩"을 요구했습니다). 작품 : SELECT REPLACE(STR('1',3),' ','0')나누기 : SELECT REPLACE(STR('1A',3),' ','0'). 사용자가 입력 문자열에 문자를 입력했을 때 오늘 화상을 입었고 그 경우를 테스트하지 못했습니다.
— Jeff Mergler

@Unbound 이것이 작동하는 방식입니다. 포스터는 이미 말합니다. 다른 모든 제안과 마찬가지로 잘린 값보다 ***을 반환하는 것이 더 좋으며 매개 변수가 잘못되었음을 나타냅니다.
— 마크 길로트

32

다음은 원하는 너비로 왼쪽 패딩을위한보다 일반적인 기술입니다.

declare @x     int     = 123 -- value to be padded
declare @width int     = 25  -- desired width
declare @pad   char(1) = '0' -- pad character

select right_justified = replicate(
                           @pad ,
                           @width-len(convert(varchar(100),@x))
                           )
                       + convert(varchar(100),@x)

그러나 음수 값을 처리하고 선행 0을 채우면이 방법이나 다른 제안 된 기술이 작동하지 않습니다. 다음과 같은 것을 얻을 수 있습니다.

00-123

[아마도 당신이 원하지 않는 것]

따라서… 몇 가지 추가 후프를 뛰어 넘어야합니다. 음수의 형식을 올바르게 지정하는 한 가지 방법이 있습니다.

declare @x     float   = -1.234
declare @width int     = 20
declare @pad   char(1) = '0'

select right_justified = stuff(
         convert(varchar(99),@x) ,                            -- source string (converted from numeric value)
         case when @x < 0 then 2 else 1 end ,                 -- insert position
         0 ,                                                  -- count of characters to remove from source string
         replicate(@pad,@width-len(convert(varchar(99),@x)) ) -- text to be inserted
         )

하나는주의해야 convert()통화가 지정해야 [n]varchar절단으로 변환 된 결과를 저장하기에 충분한 길이를.


2
@StenPetrov, 감사합니다. 그것은 모두 당신이 성취하려고하는 것에 달려 있습니다. 대규모 실제 프로덕션 데이터베이스에서 내가 배우는 한 가지는 일종의 나쁜 데이터가 있다는 것입니다. 가능하다면 오전 3시 전화를 피하고 싶습니다. ^)
— Nicholas Carey

:) 여전히 3AM 호출이 올 때 나는 10 개의 복잡한 라인보다 1 개의 간단한 라인을 읽어야합니다. 변수를 추가하면 상황이 더욱 악화됩니다. 특히 다른 팀 구성원이 즉시 계산하기로 결정하고 음이 아닌 @ 폭을 확인하지 않은 경우 ...
— Sten Petrov

추가 된 변수는 일반화를위한 것입니다. 값을 하드 코딩 할 수 있습니다. 하나의 라이너의 경우 스칼라 함수를 만들 수 있습니다. 그러면 하나의 라이너가 있습니다.
— Gerard ONeill

30

다음은 SQL Server Express 2012에서 사용하는 Hogan의 답변 변형입니다.

SELECT RIGHT(CONCAT('000', field), 3)

필드가 문자열인지 아닌지 걱정하는 대신 CONCAT어쨌든 문자열을 출력하기 때문에 필드 입니다. 분야가 될 수 또한 경우에 NULL사용하는 ISNULL기능을 입지 않도록해야 할 수 있습니다 NULL결과를.

SELECT RIGHT(CONCAT('000', ISNULL(field,'')), 3)

1
내가 기억하는 한 CONCAT은 값이 null 인 경우 값을 무시하므로 첫 번째 값은 정상적으로 작동합니다.
— Marie

이 솔루션은 필드 길이에 관계없이 작동합니다
— Unbound

23

나는 항상 다음 방법이 매우 유용하다는 것을 알았습니다.

REPLICATE('0', 5 - LEN(Job.Number)) + CAST(Job.Number AS varchar) as 'NumberFull'

15

모든 상황에 적합한이 기능을 사용하십시오.

CREATE FUNCTION dbo.fnNumPadLeft (@input INT, @pad tinyint)
RETURNS VARCHAR(250)
AS BEGIN
    DECLARE @NumStr VARCHAR(250)

    SET @NumStr = LTRIM(@input)

    IF(@pad > LEN(@NumStr))
        SET @NumStr = REPLICATE('0', @Pad - LEN(@NumStr)) + @NumStr;

    RETURN @NumStr;
END

샘플 출력

SELECT [dbo].[fnNumPadLeft] (2016,10) -- returns 0000002016
SELECT [dbo].[fnNumPadLeft] (2016,5) -- returns 02016
SELECT [dbo].[fnNumPadLeft] (2016,2) -- returns 2016
SELECT [dbo].[fnNumPadLeft] (2016,0) -- returns 2016 

숫자 와 문자열 에서 작동하기 때문에 허용되는 답변이어야합니다 . 그리고 함수를 사용하지 않으려는 경우 (그렇지 않은 이유는) DECLARE @NumStr VARCHAR(250) = '2016'; SELECT REPLICATE('0', 12 - LEN(@NumStr)) + @NumStr;위와 같은 Salar의 첫 번째 예제를 반환합니다. 감사합니다 Salar.
— Jeff Mergler

위의 내 의견에는 오타가 포함되어 있어야합니다 . 위의 첫 번째 예제에서 DECLARE @NumStr VARCHAR(250) = '2016'; SELECT REPLICATE('0', 10 - LEN(@NumStr)) + @NumStr;반환 0000002016됩니다.
— Jeff Mergler

@ Jeffeffergler-숫자와 문자열에서 어떻게 작동합니까? 정수 매개 변수를받는 함수입니다. 문제는 줄에 관한 것이었다.
— 호건

5

기존 데이터를 업데이트하려는 경우 다음 쿼리가 있습니다.

update SomeEventTable set eventTime=RIGHT('00000'+ISNULL(eventTime, ''),5)

3

정수의 경우 int에서 varchar로 암시 적 변환을 사용할 수 있습니다.

SELECT RIGHT(1000 + field, 3)

4
그러나 충분히 큰 값을 지정하면 실패합니다. 음수 값의 경우 흥미로운 결과를 얻을 수 있습니다.
— Nicholas Carey

3

나는 그것을 공유하려고 생각했던 오래된 티켓을 알고 있습니다.

이 코드에서 해결책을 찾고 있습니다. 모든 버전의 MSSQL에서 작동하는지 확실하지 않은 경우 MSSQL 2016이 있습니다.

declare @value as nvarchar(50) = 23
select REPLACE(STR(CAST(@value AS INT) + 1,4), SPACE(1), '0') as Leadingzero

"0023"을 리턴합니다. STR 함수의 4는 값을 포함한 전체 길이입니다. 예제 4, 23 및 123은 모두 STR에 4를 가지며 올바른 양의 0이 추가됩니다. 늘리거나 줄일 수 있습니다. 23의 길이를 얻을 필요가 없습니다.

편집 : 나는 @Anon post와 동일하게 보입니다.


2

고정 크기의 varchar (또는 문자열) 출력이 필요할 때 입력으로 정수 열과 비슷한 문제가 발생했습니다. 예를 들어 1 ~ '01', 12 ~ '12'입니다. 이 코드는 작동합니다 :

SELECT RIGHT(CONCAT('00',field::text),2)

입력 값이 varchar 열인 경우 주조 부품을 피할 수 있습니다.


2

좀 더 역동적 인 접근 방식을 시도해보십시오.

declare @val varchar(5)
declare @maxSpaces int
set @maxSpaces = 3
set @val = '3'
select concat(REPLICATE('0',@maxSpaces-len(@val)),@val)

2

고정 길이로 시도하십시오.

select right('000000'+'123',5)

select REPLICATE('0', 5 - LEN(123)) + '123'

1

특정 길이 (9)까지의 요구 사항이 있었기 때문에 이것을 썼습니다. 입력에 패딩이 필요한 경우 @pattern 만 사용하여 왼쪽을 채 웁니다. 항상 @pattern에 정의 된 길이를 반환해야합니다.

declare @charInput as char(50) = 'input'

--always handle NULL :)
set @charInput = isnull(@charInput,'')

declare @actualLength as int = len(@charInput)

declare @pattern as char(50) = '123456789'
declare @prefLength as int = len(@pattern)

if @prefLength > @actualLength
    select Left(Left(@pattern, @prefLength-@actualLength) + @charInput, @prefLength)
else
    select @charInput

1234 입력을 반환


1

간단합니다

처럼:

DECLARE @DUENO BIGINT
SET @DUENO=5

SELECT 'ND'+STUFF('000000',6-LEN(RTRIM(@DueNo))+1,LEN(RTRIM(@DueNo)),RTRIM(@DueNo)) DUENO

0

SQL Server 2008에서 날짜를 DATETIMEOFFSET로 변환하기 위해 시간대 오프셋을 표준 시간대 문자열로 변환하는 방법을 알아 내기 위해 여기에 왔습니다.

따라서 음수와 양수에 대처하는 1 가지 방법이 필요합니다. 필요한 경우 앞에 0을 두 문자로 형식화하십시오. Anons 답변에 가까워졌지만 음수 시간대 값이 0-5필요하지 않고 나올 것입니다-05

그래서 그의 대답에 약간의 조정으로, 이것은 모든 시간대 시간 변환에 작동합니다

DECLARE @n INT = 13 -- Works with -13, -5, 0, 5, etc
SELECT CASE 
    WHEN @n < 0 THEN '-' + REPLACE(STR(@n * -1 ,2),' ','0') 
    ELSE '+' + REPLACE(STR(@n,2),' ','0') END + ':00'

-1

bigint 및 하나의 선행 0 또는 다른 단일 문자 (최대 20 자 반환)를 제공하고 입력 수 길이보다 작은 결과 길이를 허용하는이 기능을 만들었습니다.

create FUNCTION fnPadNum (
  @Num BIGINT --Number to be padded, @sLen BIGINT --Total length of results , @PadChar varchar(1))
  RETURNS VARCHAR(20)
  AS
  --Pads bigint with leading 0's
            --Sample:  "select dbo.fnPadNum(201,5,'0')" returns "00201"
            --Sample:  "select dbo.fnPadNum(201,5,'*')" returns "**201"
            --Sample:  "select dbo.fnPadNum(201,5,' ')" returns "  201"
   BEGIN
     DECLARE @Results VARCHAR(20)
     SELECT @Results = CASE 
     WHEN @sLen >= len(ISNULL(@Num, 0))
     THEN replicate(@PadChar, @sLen - len(@Num)) + CAST(ISNULL(@Num, 0) AS VARCHAR)
     ELSE CAST(ISNULL(@Num, 0) AS VARCHAR)
     END

     RETURN @Results
     END
     GO

     --Usage:
      SELECT dbo.fnPadNum(201, 5,'0')
      SELECT dbo.fnPadNum(201, 5,'*')
      SELECT dbo.fnPadNum(201, 5,' ')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.