Funkcja PadLeft w T-SQL

113

Mam następującą tabelę A:

id
----
1
2
12
123
1234

Muszę uzupełnić idwartości z lewej strony zerami:

id
----
0001
0002
0012
0123
1234

Jak mogę to osiągnąć?

Gali
źródło

Odpowiedzi:

197

Myślę, że to może być to, czego szukasz:

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

FROM tableA

lub

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

FROM tableA

Nie testowałem składni w drugim przykładzie. Nie jestem pewien, czy to działa w 100% - może wymagać pewnych poprawek - ale przekazuje ogólną ideę, jak uzyskać pożądany wynik.

EDYTOWAĆ

Aby rozwiązać problemy wymienione w komentarzach ...

@ pkr298 - Tak STR działa tylko na liczbach ... Pole OP to ID ... stąd tylko liczba.

@Desolator - Oczywiście to nie zadziała ... Pierwszy parametr ma 6 znaków. Możesz zrobić coś takiego:

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

teoretycznie powinno to przesunąć słupki bramki ... ponieważ liczba rośnie, ZAWSZE powinno działać ... niezależnie od tego, czy jest 1 czy 123456789 ...

Więc jeśli twoja maksymalna wartość to 123456 ... zobaczysz 0000123456, a jeśli twoja minimalna wartość to 1, zobaczysz 0000000001

Patrick
źródło
4
STR () działa tylko na liczbach (lub liczbach w polach łańcuchowych). Ten kod zepsuje się, jeśli używasz go w polu varchar, które zakładasz, że ma liczbę, ale jeden z rekordów zawiera złe (nieliczbowe) dane. W tym przypadku funkcja RIGHT () nie ulegnie awarii.
pkr298,
1
Funkcja STR () nie będzie działać, jeśli liczba jest większa długość (np STR(123456, 4)powróci****
2
@Desolator Dodałem odpowiedź i poprawkę, aby ułatwić dodany scenariusz.
Patrick,
67

SQL Server obsługuje teraz funkcję FORMAT począwszy od wersji 2012, więc:

SELECT FORMAT(id, '0000') FROM TableA

da rade.

Jeśli Twój identyfikator lub kolumna jest w a varchari przedstawia liczbę, którą najpierw przekonwertujesz:

SELECT FORMAT(CONVERT(INT,id), '0000') FROM TableA
CrimsonKing
źródło
Zręczne i proste, dzięki! Biorąc pod uwagę datę pierwotnego pytania, powinna to być teraz oficjalna odpowiedź;)
David Gunderson
1
Jeśli id ​​jest ciągiem, możesz najpierw przekonwertować go na liczbę całkowitą - wybierz format (convert (int, id), '0000')
CrimsonKing
Przepraszam, ale głosuję przeciw, ponieważ ta droga jest NAPRAWDĘ powolna. Przejechanie 90 rzędów zajęło całe cztery sekundy, podczas gdy zaakceptowana odpowiedź była natychmiastowa. Jest to bardzo poważna wada, a FORMAT powinien być używany tylko na jednym lub dwóch rekordach, maks. W przeciwnym razie jest bezużyteczny ze względu na bardzo słabą wydajność.
Shadow Wizard is Ear For You
@ShadowWizard Widzę natychmiastową wydajność przy użyciu FORMATU z tysiącami wierszy.
JohnnyHK,
@JohnnyHK no może coś z projektem tabeli lub innymi dziwactwami db, ale mimo to ... faktem jest, że dla mnie było to bardzo wolne, podczas gdy w drugą stronę było szybkie.
Shadow Wizard is 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

Wynik

----
0001
0002
0012
0123
1234
Mikael Eriksson
źródło
43

Stary post, ale może to komuś pomoże:

Aby zakończyć, dopóki nie skończy się 4 niepustymi znakami:

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

Aby ukończyć do 10:

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

Jeśli kolumna jest numeryczna , najpierw przekonwertuj ją na varchar z takim kodem:

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

Aby uzupełnić do 10 z polem numerycznym:

SELECT RIGHT ('0000000000'+Convert(nvarchar(20), COLUMNNAME), 10) FROM TABLENAME;
Marcelo Myara
źródło
1
@ SilverM-A nie ma narzędzia do dodawania 0 przed liczbą, ponieważ i tak zostaną one zignorowane (w końcu 0003 to 3). Prawdopodobnie to, co chcesz osiągnąć, to rzutowanie tej liczby na łańcuch (varchar), a następnie użycie powyższej instrukcji.
Marcelo Myara
1
@ SilverM-A, jeśli tak jest, po prostu rzuć go za pomocą polecenia „CAST”, takiego jak: SELECT RIGHT ('0000000000' + CAST (COLUMNNAME AS VARCHAR), 10) FROM TABLENAME; Czy to to?
Marcelo Myara
@MarceloMyara to powinna być część odpowiedzi, a nie tylko komentarz. Dodałem teraz siebie.
Shadow Wizard is Ear For You
Uwaga: to najbardziej wydajna odpowiedź, bez wymyślnych funkcji, które mogą działać bardzo wolno. Dlatego dałem mu dodatkową nagrodę.
Shadow Wizard is Ear For You
12

Spróbuj tego:

SELECT RIGHT(REPLICATE('0',4)+CAST(Id AS VARCHAR(4)),4) FROM [Table A]
aporia
źródło
8

- Proszę spojrzeć na to.

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

- Mam nadzieję, że ci pomogą

Pan Wimol Prommajorm
źródło
1
Dostępne od SQL Server 2012: msdn.microsoft.com/en-us/library/hh213505.aspx
Styxxy
5

Działa to w przypadku łańcuchów, liczb całkowitych i liczb:

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

Gdzie 4jest pożądana długość. Działa dla liczb z więcej niż 4 cyframi, zwraca pusty ciąg dla NULLwartości.

Piotr Nawrot
źródło
3

Jeśli ktoś nadal jest zainteresowany, znalazłem ten artykuł na DATABASE.GUIDE:
Left Padding in SQL Server - 3 LPAD () Equivalents

Krótko mówiąc, w tym artykule wymieniono 3 metody.
Powiedzmy, że Twój identyfikator = 12 i chcesz, aby był wyświetlany jako 0012.

Metoda 1 - użycie funkcji RIGHT ()
Pierwsza metoda używa funkcji RIGHT () do zwrócenia tylko prawej części ciągu, po dodaniu kilku wiodących zer.

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

Wynik:
0012

Metoda 2 - użyj kombinacji RIGHT () i REPLICATE ()
Ta metoda jest prawie taka sama jak poprzednia, z tą różnicą, że po prostu zastępuję trzy zera funkcją REPLICATE ():

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

Wynik:
0012

Metoda 3 - Użyj kombinacji REPLACE () i STR ()
Ta metoda pochodzi z zupełnie innego punktu widzenia niż poprzednie metody:

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

Wynik:
0012

Sprawdź artykuł, jest bardziej dogłębna analiza z przykładami.

kfed
źródło
2

To jest to, czego zwykle używam, gdy potrzebuję uzupełnić wartość.

SET @PaddedValue = REPLICATE('0', @Length - LEN(@OrigValue)) + CAST(@OrigValue as VARCHAR)
KenB
źródło
1

Potrzebowałem tego w funkcji na serwerze SQL i poprawiłem nieco odpowiedź Patryka.

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
źródło
1

Utwórz funkcję:

    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

Przykład:

Select dbo.PadLeft('123456','0',8)
mehrdad
źródło
Jeszcze uwaga na temat standardów, nie zawracałbym sobie głowy sprawdzaniem IsNull, jeśli wartość jest równa null, funkcja powinna nadal zwracać wartość null dla tej wartości, ponieważ jest to standardowe zachowanie funkcji wbudowanych. Jeśli przekonwertujemy wszystko na wartość różną od null, wywołujący nie będzie już mógł używać operacji logicznych o wartości null, których w przeciwnym razie oczekiwałby. (Null w wielu moich tabelach oznacza „nie określono” i należy użyć wartości domyślnej.SELECT @var = LTRIM(RTRIM(@Text))
Chris Schaller
1

Stworzyłem funkcję:

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;

Użyj: wybierz dbo.fnPadLeft (123, 10)

Zwroty: 0000000123

Anne Lord
źródło
0

Coś całkiem zgodnego z ODBC w razie potrzeby może wyglądać następująco:

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

Wynika to z faktu, że liczbę cyfr dla liczby o podstawie 10 można znaleźć przez integralną składową jej dziennika. Z tego możemy odjąć go od żądanej szerokości wypełnienia. Powtórzenie zwróci nullwartości poniżej 1, więc potrzebujemy ifnull.

Brett Ryan
źródło
0

Moje rozwiązanie nie jest wydajne, ale pomogło mi w sytuacji, gdy wartości (numery czeków bankowych i nr ref. Przelewu) były przechowywane jako varchar, gdzie niektóre wpisy miały wartości alfanumeryczne i musiałem dopełniać, jeśli długość jest mniejsza niż 6 znaków.

Pomyśl o udostępnieniu, jeśli ktoś znajdzie się w tej samej sytuacji

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
źródło
0

Prostym przykładem może być

    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
źródło
0

Stworzyłem w tym celu funkcję, w której możesz określić żądaną długość znaków wyjściowych:

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

Przykładowe wyniki

Jermaine
źródło
-5

Bardziej wydajnym sposobem jest:

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

The result :
id
----
1
2
12
123
1234
SECUBE
źródło
6
Jak to odpowiada na pytanie PO dotyczące wypełniania zerami?
Filburt