Hàm PadLeft trong T-SQL


113

Tôi có bảng A sau:

id
----
1
2
12
123
1234

Tôi cần phải đệm trái các idgiá trị bằng số 0:

id
----
0001
0002
0012
0123
1234

Làm thế nào tôi có thể đạt được điều này?

Câu trả lời:


197

Tôi tin rằng đây có thể là những gì bạn đang tìm kiếm:

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

FROM tableA

hoặc là

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

FROM tableA

Tôi chưa thử nghiệm cú pháp trong ví dụ thứ 2. Tôi không chắc liệu điều đó có hoạt động 100% hay không - nó có thể yêu cầu một số điều chỉnh - nhưng nó truyền đạt ý tưởng chung về cách có được đầu ra mong muốn của bạn.

BIÊN TẬP

Để giải quyết các mối quan tâm được liệt kê trong các bình luận ...

@ pkr298 - Có STR chỉ hoạt động trên các số ... Trường của OP là ID ... do đó chỉ là số.

@Desolator - Tất nhiên điều đó sẽ không hoạt động ... tham số Đầu tiên dài 6 ký tự. Bạn có thể làm điều gì đó như:

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

điều này về mặt lý thuyết sẽ di chuyển các bài đăng mục tiêu ... khi con số lớn hơn, nó sẽ LUÔN hoạt động .... bất kể là 1 hay 123456789 ...

Vì vậy, nếu giá trị tối đa của bạn là 123456 ... bạn sẽ thấy 0000123456 và nếu giá trị tối thiểu của bạn là 1, bạn sẽ thấy 0000000001


4
STR () chỉ hoạt động trên số (hoặc số trong trường chuỗi). Mã này bị hỏng nếu bạn đang sử dụng nó trên trường varchar mà bạn cho là có một số nhưng một trong các bản ghi có dữ liệu xấu (không phải là số). Hàm RIGHT () sẽ không bị hỏng trong trường hợp này.
pkr298,

1
STR () chức năng sẽ không hoạt động nếu số là chiều dài lớn hơn (ví dụ như STR(123456, 4)sẽ trở lại****

2
@Desolator Tôi đã thêm phản hồi và bản sửa lỗi để tạo thuận lợi cho tình huống bạn đã thêm.
Patrick

66

SQL Server hiện hỗ trợ chức năng FORMAT bắt đầu từ phiên bản 2012, vì vậy:

SELECT FORMAT(id, '0000') FROM TableA

sẽ thực hiện thủ thuật.

Nếu id hoặc cột của bạn ở dạng a varcharvà đại diện cho một số bạn chuyển đổi đầu tiên:

SELECT FORMAT(CONVERT(INT,id), '0000') FROM TableA

Slick và đơn giản, cảm ơn! Với ngày của câu hỏi ban đầu, đây sẽ là câu trả lời chính thức;)
David Gunderson

1
Nếu id là một chuỗi sau đó bạn có thể chuyển nó sang số nguyên đầu tiên - chọn định dạng (convert (int, id), '0000')
CrimsonKing

Xin lỗi nhưng tôi phản đối vì cách này THỰC SỰ chậm. Mất cả bốn giây để chạy hơn 90 hàng, trong khi câu trả lời được chấp nhận là ngay lập tức. Đây là một nhược điểm rất lớn và FORMAT chỉ nên được sử dụng trên một hoặc hai bản ghi, tối đa. Nếu không, nó vô dụng do hiệu suất rất kém.
Shadow Wizard là Ear For You

@ShadowWizard Tôi đang thấy hiệu suất tức thì khi sử dụng FORMAT với 1000 hàng.
JohnnyHK

@JohnnyHK cũng có thể là một cái gì đó với thiết kế bảng hoặc các điều kỳ quặc khác của db, nhưng vẫn ... thực tế là đối với tôi nó thực sự chậm trong khi cách khác lại nhanh.
Shadow Wizard là Ear For You,


43

Bài cũ, nhưng có thể điều này sẽ giúp ai đó:

Để hoàn thành cho đến khi nó kết thúc với 4 ký tự không trống:

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

Để hoàn thành cho đến 10:

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

Trong trường hợp cột là số , hãy chuyển đổi nó thành varchar trước với mã như vậy:

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

Và để hoàn thành cho đến 10 với một trường số:

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

1
@ SilverM-A, không có tiện ích nào để thêm các số 0 vào trước một số, vì chúng sẽ bị bỏ qua dù sao (0003 sau cùng là 3). Có thể những gì bạn muốn thực hiện là truyền số đó thành một chuỗi (varchar) và sau đó sử dụng câu lệnh trên.
Marcelo Myara

1
@ SilverM-A, nếu đúng như vậy, chỉ cần truyền nó bằng lệnh "CAST" như: SELECT RIGHT ('0000000000' + CAST (COLUMNNAME AS VARCHAR), 10) FROM TABLENAME; Là nó?
Marcelo Myara

@MarceloMyara đây phải là một phần của câu trả lời, không chỉ là một bình luận. Đã thêm ngay chính tôi.
Shadow Wizard là Ear For You

Lưu ý: đây là câu trả lời hiệu quả nhất, không có chức năng ưa thích nào có thể thực sự chậm. Do đó, tôi đã cho nó thêm tiền thưởng.
Shadow Wizard là Ear For You,

12

Thử cái này:

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


5

Điều này hoạt động đối với chuỗi, số nguyên và số:

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

4Chiều dài mong muốn ở đâu . Hoạt động với các số có hơn 4 chữ số, trả về chuỗi trống trên NULLgiá trị.


3

Nếu ai đó vẫn quan tâm, tôi đã tìm thấy bài viết này trên DATABASE.GUIDE:
Left Padding trong SQL Server - 3 LPAD () Tương đương

Tóm lại, có 3 phương pháp được đề cập trong bài viết đó.
Giả sử id của bạn = 12 và bạn cần nó hiển thị là 0012.

Phương pháp 1 - Sử dụng hàm RIGHT ()
Phương pháp đầu tiên sử dụng hàm RIGHT () để chỉ trả về phần ngoài cùng bên phải của chuỗi, sau khi thêm một số số 0 ở đầu.

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

Kết quả:
0012

Phương pháp 2 - Sử dụng sự kết hợp của RIGHT () và REPLICATE ()
Phương thức này gần giống như phương pháp trước đó, với sự khác biệt duy nhất là tôi chỉ cần thay thế ba số không bằng hàm REPLICATE ():

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

Kết quả:
0012

Phương pháp 3 - Sử dụng kết hợp REPLACE () và STR ()
Phương pháp này xuất phát từ một góc độ hoàn toàn khác với các phương pháp trước đó:

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

Kết quả:
0012

Kiểm tra bài viết, có phân tích sâu hơn với các ví dụ.


2

Đây là những gì tôi thường sử dụng khi tôi cần thêm một giá trị.

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

1

Tôi cần điều này trong một hàm trên máy chủ SQL và đã điều chỉnh câu trả lời của Patrick một chút.

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'

1

Tạo chức năng:

    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

Thí dụ:

Select dbo.PadLeft('123456','0',8)

Chỉ là một điểm về tiêu chuẩn, tôi sẽ không bận tâm với việc kiểm tra IsNull, nếu giá trị là null thì hàm vẫn phải trả về null cho giá trị đó vì đây là hành vi tiêu chuẩn cho các hàm nội trang. Nếu chúng ta chuyển đổi mọi thứ thành giá trị không phải null thì người gọi sẽ không thể sử dụng các hoạt động logic null mà họ có thể đang mong đợi. (Null trong nhiều bảng phương tiện của tôi 'không xác định' và một giá trị mặc định nên được sử dụng.SELECT @var = LTRIM(RTRIM(@Text))
Chris Schaller

1

Tôi đã tạo một hàm:

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;

Sử dụng: chọn dbo.fnPadLeft (123, 10)

Trả về: 0000000123


0

Một cái gì đó tương đối tuân thủ ODBC nếu cần có thể như sau:

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

Điều này dựa trên thực tế là số lượng chữ số của một số cơ số 10 có thể được tìm thấy bằng thành phần tích phân của nhật ký của nó. Từ đó chúng ta có thể trừ nó khỏi chiều rộng đệm mong muốn. Lặp lại sẽ trả về nullcác giá trị dưới 1 vì vậy chúng ta cần ifnull.


0

Giải pháp của tôi không hiệu quả nhưng đã giúp tôi trong trường hợp các giá trị (số séc ngân hàng và số tham chiếu chuyển khoản ngân hàng) được lưu trữ dưới dạng varchar trong đó một số mục nhập có giá trị số alpha và tôi phải đệm nếu độ dài nhỏ hơn 6 ký tự.

Suy nghĩ để chia sẻ nếu ai đó gặp phải tình huống tương tự

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

0

Một ví dụ đơn giản sẽ là

    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))

0

Tôi đã tạo một hàm để thực hiện việc này, nơi bạn có thể chỉ định độ dài ký tự đầu ra mong muốn:

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

Kết quả ví dụ


-5

Cách hiệu quả hơn là:

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

The result :
id
----
1
2
12
123
1234

6
Làm thế nào điều này trả lời câu hỏi OPs về đệm bằng số không?
Filburt,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.