Функция 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% - это может потребовать некоторой настройки - но он передает общее представление о том, как получить желаемый результат.

РЕДАКТИРОВАТЬ

Чтобы решить проблемы, перечисленные в комментариях ...

@ 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 () работает только с числами (или числами в строковых полях). Этот код не работает, если вы используете его в поле varchar, которое, как вы предполагаете, имеет число, но одна из записей имеет неверные (нечисловые) данные. Функция RIGHT () в этом случае не сломается.
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
CrimsonKing
источник
Лаконично и просто, спасибо! Учитывая дату исходного вопроса, теперь это должен быть официальный ответ;)
Дэвид Гандерсон,
1
Если id является строкой, вы можете сначала преобразовать ее в целое число - выберите формат (convert (int, id), '0000')
CrimsonKing
Извините, но я голосую против, потому что этот способ ДЕЙСТВИТЕЛЬНО медленный. На прохождение 90 строк ушло четыре секунды, в то время как принятый ответ был мгновенным. Это очень серьезный недостаток, и FORMAT следует использовать только для одной или двух записей, максимум. В противном случае это бесполезно из-за очень плохой производительности.
Shadow Wizard - Ear For You
@ShadowWizard Я наблюдаю мгновенную производительность при использовании FORMAT с тысячами строк.
JohnnyHK
@JohnnyHK ну, может быть, что-то с дизайном стола или другими причудами БД, но все же ... факт в том, что для меня это было очень медленно, в то время как другой путь был быстрым.
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

Результат

----
0001
0002
0012
0123
1234
Микаэль Эрикссон
источник
43

Старый пост, но, возможно, это кому-то поможет:

Для завершения, пока не останется 4 непустых символа:

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, нет утилиты для добавления нулей перед числом, так как они все равно будут игнорироваться (0003 в конце концов 3). Вероятно, вы хотите преобразовать это число в строку (varchar), а затем использовать приведенный выше оператор.
Марсело Мьяра
1
@ SilverM-A, если это так, просто введите его с помощью команды «CAST», например: SELECT RIGHT ('0000000000' + CAST (COLUMNNAME AS VARCHAR), 10) FROM TABLENAME; Это оно?
Марсело Мьяра
@MarceloMyara это должно быть частью ответа, а не просто комментарием. Добавил сейчас сам.
Shadow Wizard - Ear For You
Примечание: это наиболее эффективный ответ без каких-либо необычных функций, которые могли бы работать очень медленно. Следовательно, я дал ему дополнительную награду.
Shadow Wizard is Ear For You
12

Попробуй это:

SELECT RIGHT(REPLICATE('0',4)+CAST(Id AS VARCHAR(4)),4) FROM [Table A]
выражение сомнения
источник
8

- Пожалуйста, изучите это.

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

- Надеюсь, это поможет вам

Мистер Уимол Проммайорм
источник
1
Доступно с SQL Server 2012: msdn.microsoft.com/en-us/library/hh213505.aspx
Styxxy,
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

Ознакомьтесь со статьей, там более подробный анализ с примерами.

kfed
источник
2

Это то, что я обычно использую, когда мне нужно заполнить значение.

SET @PaddedValue = REPLICATE('0', @Length - LEN(@OrigValue)) + CAST(@OrigValue as VARCHAR)
KeNB
источник
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, если значение равно null, тогда функция все равно должна возвращать null для этого значения, поскольку это стандартное поведение для встроенных функций. Если мы преобразуем все в ненулевое значение, вызывающий больше не сможет использовать нулевые логические операции, которых они могли бы ожидать. (Нулевое значение во многих моих таблицах означает «не указано», и следует использовать значение по умолчанию.SELECT @var = LTRIM(RTRIM(@Text))
Крис Шаллер,
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 можно найти по интегральной составляющей его журнала. Из этого мы можем вычесть это из желаемой ширины отступа. Repeat вернется nullдля значений меньше 1, так что нам нужно ifnull.

Бретт Райан
источник
0

Мое решение неэффективно, но помогло мне в ситуации, когда значения (номера банковских чеков и номера банковских переводов) хранились как varchar, где некоторые записи имели буквенно-цифровые значения с ними, и мне приходилось дополнять их, если длина меньше 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
Tejasvi Hegde
источник
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

Примеры результатов

Jermaine
источник
-5

Более эффективный способ:

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

The result :
id
----
1
2
12
123
1234
SECUBE
источник
6
Как это отвечает на вопрос OP о заполнении нулями?
Filburt