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.