Функция 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

Лаконично и просто, спасибо! Учитывая дату исходного вопроса, теперь это должен быть официальный ответ;)
Дэвид Гандерсон,

1
Если id является строкой, вы можете сначала преобразовать ее в целое число - выберите формат (convert (int, id), '0000')
CrimsonKing

Извините, но я голосую против, потому что этот способ ДЕЙСТВИТЕЛЬНО медленный. На прохождение 90 строк ушло четыре секунды, в то время как принятый ответ был мгновенным. Это очень серьезный недостаток, и FORMAT следует использовать только для одной или двух записей, максимум. В противном случае это бесполезно из-за очень плохой производительности.
Shadow Wizard - Ear For You

@ShadowWizard Я наблюдаю мгновенную производительность при использовании FORMAT с тысячами строк.
JohnnyHK

@JohnnyHK ну, может быть, что-то с дизайном стола или другими причудами БД, но все же ... факт в том, что для меня это было очень медленно, в то время как другой путь был быстрым.
Shadow Wizard is Ear For You


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



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, если значение равно 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

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
Как это отвечает на вопрос OP о заполнении нулями?
Filburt
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.