Функція PadLeft в T-SQL


113

У мене є така таблиця A:

id
----
1
2
12
123
1234

Мені потрібно ліворуч змінити idзначення з нулем:

id
----
0001
0002
0012
0123
1234

Як я можу цього досягти?

Відповіді:


197

Я вважаю, що це саме те, що ви шукаєте:

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

FROM tableA

або

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

FROM tableA

Я не перевіряв синтаксис на другому прикладі. Я не впевнений, чи це працює на 100% - це може зажадати певного налаштування - але це передає загальне уявлення про те, як отримати бажаний результат.

EDIT

Для вирішення проблем, перелічених у коментарях ...

@ pkr298 - Так STR працює лише на числах ... Поле OP - це ідентифікатор ... отже, лише номер.

@Desolator - Звичайно, це не буде працювати ... Перший параметр - 6 символів. Ви можете зробити щось на кшталт:

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

це теоретично повинно переміщувати цілі постів ... оскільки число зростає, воно завжди повинно працювати .... незалежно, якщо його 1 або 123456789 ...

Отже, якщо ваше максимальне значення 123456 ... ви побачите 0000123456, а якщо ваше мінімальне значення дорівнює 1, ви побачите 0000000001


4
STR () працює лише на числах (або числах у рядкових полях). Цей код порушується, якщо ви використовуєте його у варшарському полі, яке, як ви вважаєте, має число, але одна з записів має погані (нечислові) дані. В цьому випадку функція ПРАВО () не порушиться.
pkr298

1
Функція STR () не буде працювати, якщо число більша довжина (наприклад STR(123456, 4), повернеться****

2
@Desolator Я додав відповідь та виправлення, щоб полегшити сценарій, який ви додали.
Патрік

67

Тепер SQL Server підтримує функцію FORMAT, починаючи з версії 2012 року, тому:

SELECT FORMAT(id, '0000') FROM TableA

зробить трюк.

Якщо ваш ідентифікатор або стовпець знаходиться в а varcharі представляє число, яке ви перетворюєте спочатку:

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

Гладкий і простий, дякую! З огляду на дату первинного питання, тепер це має бути офіційна відповідь;)
Девід Гундерсон

1
Якщо id - рядок, то спочатку ви можете перетворити його на ціле число - виберіть формат (convert (int, id), '0000')
CrimsonKing

Вибачте, але я заявляю, що цей шлях НАДЕЙ повільний. Пройшло чотири секунди, щоб пробігти понад 90 рядків, а прийнята відповідь була миттєвою. Це дуже великий мінус, і FORMAT слід використовувати лише на одній або двох записах, макс. Інакше це марно через дуже низьку продуктивність.
Shadow Wizard is Ear for You

@ShadowWizard Я бачу миттєву продуктивність, використовуючи FORMAT з 1000-ма рядками.
JohnnyHK

@JohnnyHK ну, можливо, щось із дизайном столу чи іншими db примхами, але все ж ... факт полягає в тому, що для мене це було дуже повільно, а інший шлях був швидким.
Shadow Wizard is Ear For You


43

Стара публікація, але, можливо, це допомагає комусь:

Щоб завершити, поки це не закінчиться чотирма непорожніми символами:

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

Для завершення до 10:

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

У разі, якщо стовпець є числовим , спочатку перетворіть його у varchar з таким кодом:

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

І заповнити до 10 числовим полем:

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

1
@ SilverM-A, немає ніякої утиліти, щоб додати 0 до числа, оскільки вони все одно будуть ігноровані (0003 - це все-таки 3). Можливо, те, що ви хочете виконати, - це привласнити це число до рядка (varchar), а потім скористатися вищевказаним висловом.
Marcelo Myara

1
@ SilverM-A, якщо це так, просто киньте його за допомогою команди "CAST" на зразок: SELECT RIGHT ("0000000000" + CAST (COLUMNNAME AS VARCHAR), 10) FROM TABLENAME; Це все?
Marcelo Myara

@MarceloMyara це має бути частиною відповіді, а не просто коментарем. Додав зараз сам.
Shadow Wizard is Ear for You

Примітка. Це найефективніший варіант відповіді, не маючи фантазійних функцій, які можуть бути дуже повільними. Отже, я надав йому додаткову нагоду.
Shadow Wizard є Ear for You,



5

Це працює для рядків, цілих чисел та чисел:

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

Де 4бажана довжина. Працює для чисел з більш ніж 4 цифрами, повертає порожній рядок за NULLзначенням.


3

Якщо когось все ще цікавить, я знайшов цю статтю на DATABASE.GUIDE:
Left Padding у SQL Server - 3 еквіваленти LPAD ()

Коротше кажучи, у цій статті є 3 методи.
Скажімо, ваш id = 12, і він потрібен для відображення як 0012.

Спосіб 1 - Використання функції RIGHT ()
Перший метод використовує функцію RIGHT () для повернення лише самої правої частини рядка після додавання декількох провідних нулів.

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

Результат:
0012

Спосіб 2 - Використання комбінації RIGHT () та REPLICATE ()
Цей метод майже такий же, як і попередній метод, з тією лише різницею, що я просто заміню три нулі функцією REPLICATE ():

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

Результат:
0012

Спосіб 3 - Використання комбінації REPLACE () та STR ()
Цей метод походить з абсолютно іншого кута до попередніх методів:

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

Результат:
0012

Перегляньте статтю, є більш глибокий аналіз із прикладами.


2

Це те, що я зазвичай використовую, коли мені потрібно зазначити значення.

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

1

Мені це було потрібно у функції на SQL-сервері та трохи коригував відповідь Патріка.

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

Створити функцію:

    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

Приклад:

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

Лише питання про стандарти, я б не переймався перевіркою IsNull, якщо значення є нульовим, тоді функція все одно повинна повернути нуль для цього значення, оскільки це стандартна поведінка для вбудованих функцій. Якщо ми перетворимо все в ненульове значення, то абонент більше не зможе використовувати нульові логічні операції, які вони інакше можуть очікувати. (Нуль у багатьох моїх таблицях означає "не вказано", і слід використовувати значення за замовчуванням.SELECT @var = LTRIM(RTRIM(@Text))
Chris Schaller

1

Я створив функцію:

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;

Використовуйте: виберіть dbo.fnPadLeft (123, 10)

Повернення: 0000000123


0

Щось досить сумісне з ODBC, якщо потрібно, може бути таке:

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

Це ґрунтується на тому, що кількість цифр для базового числа 10 можна знайти за інтегральною складовою його журналу. З цього ми можемо відняти його від потрібної ширини накладки. Повтор повернеться nullдля значень нижче 1, тому нам потрібно ifnull.


0

Моє рішення не є ефективним, але допомогло мені в ситуації, коли значення (банківські чекові номери та номер переказу рахунку) зберігалися як варчар, де деякі записи мали параметри цифрових значень, і мені довелося прошивати, якщо довжина менше 6 символів.

Думав поділитися, якщо хтось стикається з тією ж ситуацією

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

Простий приклад може бути

    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

Я створив для цього функцію, де можна вказати бажану довжину вихідного символу:

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

Приклад результатів


-5

Більш ефективний спосіб:

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

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

6
Як це відповідає на питання ОП щодо оббивки нулями?
Фільбурт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.