Fungsi PadLeft di T-SQL

113

Saya memiliki tabel A berikut:

id
----
1
2
12
123
1234

Saya perlu mengesampingkan idnilai dengan nol:

id
----
0001
0002
0012
0123
1234

Bagaimana saya bisa mencapai ini?

Gali
sumber

Jawaban:

197

Saya percaya ini mungkin yang Anda cari:

SELECT padded_id = REPLACE(STR(id, 4), SPACE(1), '0') 

FROM tableA

atau

SELECT REPLACE(STR(id, 4), SPACE(1), '0') AS [padded_id]

FROM tableA

Saya belum menguji sintaks pada contoh ke-2. Saya tidak yakin apakah itu berhasil 100% - ini mungkin memerlukan beberapa penyesuaian - tetapi ini menyampaikan gagasan umum tentang cara mendapatkan keluaran yang Anda inginkan.

EDIT

Untuk mengatasi masalah yang tercantum di komentar ...

@ pkr298 - Ya STR hanya bekerja pada angka ... Bidang OP adalah ID ... maka angka saja.

@ Desolator - Tentu saja itu tidak akan berhasil ... Parameter pertama adalah 6 karakter. Anda dapat melakukan sesuatu seperti:

SELECT REPLACE(STR(id,
(SELECT LEN(MAX(id)) + 4 FROM tableA)), SPACE(1), '0') AS [padded_id] FROM tableA

ini secara teoritis harus memindahkan tiang gawang ... karena jumlahnya semakin besar, itu harus SELALU berfungsi .... terlepas dari apakah itu 1 atau 123456789 ...

Jadi jika nilai maksimal Anda adalah 123456 ... Anda akan melihat 0000123456 dan jika nilai minimum Anda adalah 1, Anda akan melihat 0000000001

Patrick
sumber
4
STR () hanya bekerja pada angka (atau angka dalam bidang string). Kode ini rusak jika Anda menggunakannya di bidang varchar yang Anda asumsikan memiliki angka tetapi salah satu rekaman memiliki data (non-numerik) yang buruk. Fungsi RIGHT () tidak akan rusak dalam kasus ini.
pkr298
1
Fungsi STR () tidak akan berfungsi jika nomornya lebih panjang (misalnya STR(123456, 4)akan mengembalikan****
2
@Desolator Saya telah menambahkan tanggapan dan perbaikan untuk memfasilitasi skenario yang Anda tambahkan.
Patrick
66

SQL Server sekarang mendukung fungsi FORMAT mulai dari versi 2012, jadi:

SELECT FORMAT(id, '0000') FROM TableA

akan melakukan triknya.

Jika id atau kolom Anda ada di a varchardan mewakili angka yang Anda konversi dulu:

SELECT FORMAT(CONVERT(INT,id), '0000') FROM TableA
CrimsonKing
sumber
Licin dan sederhana, terima kasih! Mengingat tanggal pertanyaan awal, ini sekarang harus menjadi jawaban resmi;)
David Gunderson
1
Jika id adalah string maka Anda dapat mengubahnya menjadi integer terlebih dahulu - pilih format (convert (int, id), '0000')
CrimsonKing
Maaf tapi saya downvote karena cara ini BENAR-BENAR lambat. Butuh empat detik penuh untuk menjalankan lebih dari 90 baris, sementara jawaban yang diterima instan. Ini adalah kerugian yang sangat besar, dan FORMAT hanya boleh digunakan pada satu atau dua rekaman, maks. Kalau tidak, itu tidak berguna karena kinerjanya yang sangat buruk.
Shadow Wizard adalah Ear For You
@ShadowWizard Saya melihat kinerja seketika menggunakan FORMAT dengan 1000 baris.
JohnnyHK
@JohnnyHK mungkin sesuatu dengan desain meja atau kebiasaan db lainnya, tapi tetap saja ... faktanya bagi saya itu sangat lambat sedangkan sebaliknya cepat.
Shadow Wizard adalah Ear For You
60
declare @T table(id int)
insert into @T values
(1),
(2),
(12),
(123),
(1234)

select right('0000'+convert(varchar(4), id), 4)
from @T

Hasil

----
0001
0002
0012
0123
1234
Mikael Eriksson
sumber
43

Pos lama, tapi mungkin ini membantu seseorang:

Untuk menyelesaikan hingga berakhir dengan 4 karakter tidak kosong:

SELECT RIGHT ('0000'+COLUMNNAME, 4) FROM TABLENAME;

Untuk menyelesaikan hingga 10:

SELECT RIGHT ('0000000000'+COLUMNNAME, 10) FROM TABLENAME;

Jika kolomnya numerik , ubah dulu menjadi varchar dengan kode seperti ini:

Select RIGHT('0000'+Convert(nvarchar(20), COLUMNNAME), 4)
From TABLENAME

Dan untuk melengkapi sampai 10 dengan bidang numerik:

SELECT RIGHT ('0000000000'+Convert(nvarchar(20), COLUMNNAME), 10) FROM TABLENAME;
Marcelo Myara
sumber
1
@ SilverM-A, tidak ada utilitas untuk menambahkan 0 sebelum angka, karena bagaimanapun juga mereka akan diabaikan (0003 adalah 3). Mungkin yang ingin Anda capai adalah mentransmisikan nomor itu ke string (varchar) dan kemudian menggunakan pernyataan di atas.
Marcelo Myara
1
@ SilverM-A, jika itu kasusnya, cukup gunakan perintah "CAST" seperti: SELECT RIGHT ('0000000000' + CAST (COLUMNNAME AS VARCHAR), 10) FROM TABLENAME; Itu saja?
Marcelo Myara
@MarceloMyara ini harus menjadi bagian dari jawaban, bukan sekedar komentar. Ditambahkan sekarang sendiri.
Shadow Wizard adalah Ear For You
Catatan: ini adalah jawaban yang paling efisien, tanpa fungsi mewah yang mungkin menjadi sangat lambat. Oleh karena itu saya telah memberikannya hadiah ekstra.
Shadow Wizard adalah Ear For You
12

Coba ini:

SELECT RIGHT(REPLICATE('0',4)+CAST(Id AS VARCHAR(4)),4) FROM [Table A]
aporia
sumber
8

- Tolong periksa ini.

select FORMAT(1, 'd4');
select FORMAT(2, 'd4');
select FORMAT(12, 'd4');
select FORMAT(123, 'd4');
select FORMAT(1234, 'd4');

- Saya harap ini akan membantu Anda

Tuan Wimol Prommajorm
sumber
1
Tersedia sejak SQL Server 2012: msdn.microsoft.com/en-us/library/hh213505.aspx
Styxxy
5

Ini berfungsi untuk string, integer, dan numerik:

SELECT CONCAT(REPLICATE('0', 4 - LEN(id)), id)

Dimana 4panjang yang diinginkan. Berfungsi untuk angka dengan lebih dari 4 digit, mengembalikan NULLnilai string kosong .

Piotr Nawrot
sumber
3

Jika ada yang masih tertarik, saya menemukan artikel ini di DATABASE.GUIDE:
Left Padding in SQL Server - 3 LPAD () Equivalents

Singkatnya, ada 3 metode yang disebutkan dalam artikel itu.
Misalkan id Anda = 12 dan Anda membutuhkannya untuk ditampilkan sebagai 0012.

Metode 1 - Gunakan Fungsi RIGHT ()
Metode pertama menggunakan fungsi RIGHT () untuk mengembalikan hanya bagian paling kanan dari string, setelah menambahkan beberapa nol di depan.

SELECT RIGHT('00' + '12', 4);

Hasil:
0012

Metode 2 - Gunakan Kombinasi RIGHT () dan REPLICATE ()
Metode ini hampir sama dengan metode sebelumnya, dengan satu-satunya perbedaan adalah saya cukup mengganti tiga nol dengan fungsi REPLICATE ():

SELECT RIGHT(REPLICATE('0', 2) + '12', 4);

Hasil:
0012

Metode 3 - Gunakan Kombinasi REPLACE () dan STR ()
Metode ini berasal dari sudut yang sama sekali berbeda dengan metode sebelumnya:

SELECT REPLACE(STR('12', 4),' ','0');

Hasil:
0012

Simak artikelnya, ada analisis lebih mendalam dengan contoh.

kfed
sumber
2

Inilah yang biasanya saya gunakan saat saya perlu memberi nilai.

SET @PaddedValue = REPLICATE('0', @Length - LEN(@OrigValue)) + CAST(@OrigValue as VARCHAR)
KenB
sumber
1

Saya membutuhkan ini dalam sebuah fungsi di SQL server dan menyesuaikan jawaban Patrick sedikit.

declare @dossierId int = 123
declare @padded_id varchar(7)


set @padded_id = REPLACE(
              SPACE(7 - LEN(@dossierId)) + convert(varchar(7), @dossierId), 
              SPACE(1),  
              '0') 

SELECT @dossierId as '@dossierId'
      ,SPACE(LEN(@dossierId)) + convert(varchar(7)
      ,@dossierId) as withSpaces
      ,@padded_id as '@padded_id'
Bob Lokerse
sumber
1

Buat Fungsi:

    Create FUNCTION [dbo].[PadLeft]
      (
        @Text NVARCHAR(MAX) ,
        @Replace NVARCHAR(MAX) ,
        @Len INT
      )
RETURNS NVARCHAR(MAX)
AS
    BEGIN 


        DECLARE @var NVARCHAR(MAX) 

        SELECT @var = ISNULL(LTRIM(RTRIM(@Text)) , '')


        RETURN   RIGHT(REPLICATE(@Replace,@Len)+ @var, @Len)


    END

Contoh:

Select dbo.PadLeft('123456','0',8)
mehrdad
sumber
Hanya satu poin tentang standar, saya tidak akan repot dengan pemeriksaan IsNull, jika nilainya null maka fungsi tersebut masih harus mengembalikan null untuk nilai itu karena ini adalah perilaku standar untuk fungsi bawaan. Jika kita mengonversi semuanya menjadi nilai bukan nol maka pemanggil tidak akan lagi dapat menggunakan operasi logika nol yang mungkin mereka harapkan. (Null di banyak tabel saya berarti 'tidak ditentukan' dan nilai default harus digunakan.SELECT @var = LTRIM(RTRIM(@Text))
Chris Schaller
1

Saya membuat sebuah fungsi:

CREATE FUNCTION [dbo].[fnPadLeft](@int int, @Length tinyint)
RETURNS varchar(255) 
AS 
BEGIN
    DECLARE @strInt varchar(255)

    SET @strInt = CAST(@int as varchar(255))
    RETURN (REPLICATE('0', (@Length - LEN(@strInt))) + @strInt);
END;

Gunakan: pilih dbo.fnPadLeft (123, 10)

Pengembalian: 0000000123

Anne Lord
sumber
0

Sesuatu yang sesuai dengan ODBC jika diperlukan adalah sebagai berikut:

select ifnull(repeat('0', 5 - (floor(log10(FIELD_NAME)) + 1)), '')
        + cast (FIELD as varchar(10))
  from TABLE_NAME

Ini mendasarkan pada fakta bahwa jumlah digit untuk bilangan basis 10 dapat ditemukan oleh komponen integral dari lognya. Dari sini kita dapat menguranginya dari lebar bantalan yang diinginkan. Ulangi akan mengembalikan nullnilai di bawah 1 jadi kita perlu ifnull.

Brett Ryan
sumber
0

Solusi saya tidak efisien tetapi membantu saya dalam situasi di mana nilai (nomor cek bank dan no ref transfer kawat) disimpan sebagai varchar di mana beberapa entri memiliki nilai alfa numerik dengan mereka dan saya harus pad jika panjangnya lebih kecil dari 6 karakter.

Berpikir untuk berbagi jika seseorang menemukan situasi yang sama

declare @minlen int = 6
declare @str varchar(20)

set @str = '123'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 000123

set @str = '1234'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 001234

set @str = '123456'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 123456

set @str = '123456789'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 123456789

set @str = '123456789'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 123456789


set @str = 'NEFT 123456789'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: NEFT 123456789
Tejasvi Hegde
sumber
0

Contoh sederhananya adalah

    DECLARE @number INTEGER
    DECLARE @length INTEGER
    DECLARE @char   NVARCHAR(10)
    SET @number = 1
    SET @length = 5
    SET @char = '0'

    SELECT FORMAT(@number, replicate(@char, @length))
Jonathan Santiago
sumber
0

Saya membuat fungsi untuk melakukan ini, di mana Anda dapat menentukan panjang karakter keluaran yang diinginkan:

CREATE FUNCTION [dbo].[udfLeadingZero]
(
        @String VARCHAR(MAX)
,       @Len INT
)
RETURNS VARCHAR(MAX)
BEGIN
    SET @String = RIGHT(REPLICATE('0',@Len)+@String,@Len)
RETURN @String
END
GO

Hasil contoh

Jermaine
sumber
-5

Cara yang lebih efisien adalah:

Select id, LEN(id)
From TableA
Order by 2,1 

The result :
id
----
1
2
12
123
1234
SECUBE
sumber
6
Bagaimana ini menjawab pertanyaan OP tentang padding dengan nol?
Filburt