文字列に先行ゼロを埋め込んで、SQL Server 2008では3文字になるようにする


398

SQL Server 2008 R2で最初に作成されたとき、最大3文字の文字列があります。

先行ゼロで埋めたいので、元の値が「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の場合にのみ機能します。より大きなものが必要な場合は、文字列定数と2つの整数定数を必要な幅に変更する必要があります。例えば'0000' and VARCHAR(4)),4


8
私はChar(6)フィールドを持っていて、その長さはほんの2〜3文字であり、上記ではうまくいきませんでした。それを機能させるには、 '000000' + ISNULL(FIELD、 '')の周りにRTRIMを追加する必要がありました。
DWiener 2014

3
Hoganええ、それはわかりましたが、文字列がどれだけ長く機能しなかったとしても、理由がわからないほど忙しいのですが、要点は、CHAR(6)フィールドがRIGHT( '000000 '+ ISNULL(field、' ')、6)は機能しませんでしたが、RIGHT(RTRIM(' 000000 '+ ISNULL(field、' '))、6)は機能しました。
DWiener 2014

2
わかりました、文字列としてエンコードされた数値の右側にスペースがありました。
Hogan 14

3
@dwienerは、charが固定長のデータ型であるためにこの動作が発生し、char(6)は6文字の長さを意味します。実際の値が6未満の場合は、右側に空白が埋め込まれるため、提案された回答ではchar(6)の結果が正しくありません。
Giannis Paraskevopoulos 2014

2
@Hogan、はい、しかし、この質問は「sql add leading zeros」に対するtop1 googleの結果なので、他のデータベースでは、より便利な関数lpadが存在します。とにかくありがとうございました。
diralik 2017

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の場合、それは011だ11のために、001だと111のためにそれは111だ
ゲーザ

2
「00#」の代わりに「D3」を使用できます。
Vadim Ovchinnikov

1
受け入れられた回答よりもかなり遅いようですが、大量のデータを処理しない場合は、はるかに簡単です
ルート

2
論理的ではないように見えますが、FORMATはvarcharではなく、数値型と日付型でのみ機能することに注意してください。
ストラトトン、

120

安全な方法:

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

これには、'***'n <0またはn> 999 の文字列を返すという利点があります。これは、範囲外の入力を示すわかりやすいインジケータです。ここにリストされている他のメソッドは、入力を3文字のサブストリングに切り捨てることにより、警告なしに失敗します。


10
くそー、このページに着く人は誰でもこれが上に浮かぶのを助けるべきです!
MarioDS 2017年

1
この方法には注意してください。式が指定された長さを超えると、文字列は指定された長さの**を返します。たとえばstr(n、10)の場合、n = 1000000000の場合、星(*)が表示されます。
アンバウンド

これがどのように機能するかはわかりませんが、驚くほど簡単です。
RaRdEvA

1
これに注意すると、文字列はそれを壊します(そしてOPは「文字列のパディング」を要求しました)。作品:SELECT REPLACE(STR('1',3),' ','0')休憩:SELECT REPLACE(STR('1A',3),' ','0')。これは、ユーザーが入力文字列に文字を入力し、そのケースをテストできなかったときに、私を焦らせただけです。
Jeff Mergler、

@Unboundこれがどのように機能するかを意図したものであり、ポスターはすでにそれを述べています。他のすべての提案が行うように切り捨てられた値よりも***を返すほうが適切であり、パラメーターが間違っていたことを示しています。
Marc Guillot

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)

ただし、負の値を扱い、先行ゼロでパディングしている場合、これも他の推奨される手法も機能しません。次のようなものが表示されます。

00-123

[たぶんあなたが欲しかったものではない]

したがって、…いくつかの追加のフープをジャンプする必要があります。負の数を適切にフォーマットする1つのアプローチを次に示します。

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、ありがとうございます。それはすべて、達成しようとしていることに依存します。大規模な実際の運用データベースで依存することを学んだことの1つは、何らかの不良データの存在です。そして、できれば午前3時の電話は避けたい; ^)
ニコラスキャリー

:)それでも、その午前3時の呼び出しが入ってくると、10行の複雑な行ではなく、1行の単純な行を読み取る必要があります。変数を追加すると、さらに事態が悪化します。特に、別のチームメンバーがその場で計算することを決定し、負でない@widthをチェックしなかった場合...
Sten Petrov

これらの追加された変数は一般化のためだけです-値をハードコーディングできます。1つのライナーの場合は、スカラー関数を作成できます。これで、1つのライナーが作成されます。
Gerard ONeill、2015

30

以下は、SQL Server Express 2012で使用するHoganの回答の変形です。

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

フィールドが文字列であるかどうかを心配する代わりに、CONCATとにかく文字列を出力するので、私はそれだけです。さらに、フィールドがである可能性がある場合、関数が結果を取得NULLISNULLないようにするために使用が必要になる場合がありNULLます。

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

1
私が覚えている限り、CONCATは値がnullの場合は無視するだけなので、最初の値は正常に機能します。
マリー

このソリューションは、フィールドの範囲に関係なく機能します
アン

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、

@JeffMergler-これは数値と文字列でどのように機能しますか?整数パラメータを取る関数です。質問は弦についてでした。
ホーガン

5

既存のデータを更新したい人のためにここにクエリがあります:

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

3

整数の場合、intからvarcharへの暗黙的な変換を使用できます。

SELECT RIGHT(1000 + field, 3)

4
ただし、十分に大きな値を指定すると失敗します。さらに、負の値の場合、興味深い結果が得られます。
ニコラスキャリー

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を持ち、正しい量のゼロが追加されます。増減できます。23の長さを取得する必要はありません。

編集:@Anonの投稿と同じです。


3

固定長で試してください。

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

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

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)

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

1234inputを返します


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に変換するためにタイムゾーンオフセットをタイムゾーン文字列に変換する方法を具体的に理解するためにここに来ました。総計ですが、必要です。

したがって、必要に応じて、負の数と正の数を処理し、先頭にゼロを付けて2つの文字にフォーマットする1つの方法が必要です。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と1つの先行ゼロまたはその他の単一の文字(最大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.