Função PadLeft em T-SQL

113

Eu tenho a seguinte tabela A:

id
----
1
2
12
123
1234

Preciso preencher com o botão esquerdo os idvalores com zero:

id
----
0001
0002
0012
0123
1234

Como posso conseguir isso?

Gali
fonte

Respostas:

197

Eu acredito que pode ser isso que você está procurando:

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

FROM tableA

ou

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

FROM tableA

Não testei a sintaxe do segundo exemplo. Não tenho certeza se isso funciona 100% - pode exigir alguns ajustes - mas transmite a ideia geral de como obter a saída desejada.

EDITAR

Para abordar as preocupações listadas nos comentários ...

@ pkr298 - Sim, STR só funciona com números ... O campo do OP é um ID ... portanto, apenas número.

@Desolator - Claro que não vai funcionar ... o primeiro parâmetro tem 6 caracteres. Você pode fazer algo como:

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

isso deveria, teoricamente, mover os postes da baliza ... conforme o número aumenta, ele SEMPRE deve funcionar .... independentemente se for 1 ou 123456789 ...

Portanto, se seu valor máximo for 123456 ... você verá 0000123456 e se seu valor mínimo for 1, você verá 0000000001

Patrick
fonte
4
STR () funciona apenas com números (ou números em campos de string). Este código será interrompido se você o estiver usando em um campo varchar que você supõe ter um número, mas um dos registros tem dados inválidos (não numéricos). A função RIGHT () não será interrompida neste caso.
pkr298
1
A função STR () não funcionará se o número for maior (por exemplo STR(123456, 4), retornará****
2
@Desolator Eu adicionei uma resposta e correção para facilitar o cenário que você adicionou.
Patrick
67

O SQL Server agora oferece suporte à função FORMAT a partir da versão 2012, portanto:

SELECT FORMAT(id, '0000') FROM TableA

vai fazer o truque.

Se sua id ou coluna estiver em a varchare representar um número que você converte primeiro:

SELECT FORMAT(CONVERT(INT,id), '0000') FROM TableA
Rei carmesim
fonte
Liso e simples, obrigado! Dada a data da pergunta original, esta agora deve ser a resposta oficial;)
David Gunderson
1
Se id for uma string, você pode convertê-la para um inteiro primeiro - selecione o formato (convert (int, id), '0000')
CrimsonKing
Desculpe, mas eu votei negativamente porque esse caminho é MUITO lento. Levou quatro segundos inteiros para percorrer 90 linhas, enquanto a resposta aceita foi instantânea. Esta é uma grande desvantagem, e o FORMAT só deve ser usado em um ou dois registros, no máx. Caso contrário, é inútil devido ao seu desempenho muito fraco.
Shadow Wizard is Ear For You
@ShadowWizard Estou vendo um desempenho instantâneo usando FORMAT com 1000 linhas.
JohnnyHK
@JohnnyHK bem, talvez algo com o design da mesa ou outras peculiaridades do banco de dados, mas ainda ... o fato é que para mim foi muito lento enquanto o outro caminho foi rápido.
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

Resultado

----
0001
0002
0012
0123
1234
Mikael Eriksson
fonte
43

Postagem antiga, mas talvez isso ajude alguém:

Para concluir até que termine com 4 caracteres não em branco:

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

Para completar até 10:

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

Caso a coluna seja numérica , converta-a primeiro em varchar com o seguinte código:

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

E para completar até 10 com um campo numérico:

SELECT RIGHT ('0000000000'+Convert(nvarchar(20), COLUMNNAME), 10) FROM TABLENAME;
Marcelo Myara
fonte
1
@ SilverM-A, não há utilidade para adicionar 0s antes de um número, pois eles serão ignorados de qualquer maneira (0003 é 3, afinal). Provavelmente, o que você deseja realizar é converter esse número em uma string (varchar) e, em seguida, usar a instrução acima.
Marcelo Myara
1
@ SilverM-A, se for esse o caso, basta lançá-lo usando o comando "CAST" como: SELECT RIGHT ('0000000000' + CAST (COLUMNNAME AS VARCHAR), 10) FROM TABLENAME; É isso?
Marcelo Myara
@MarceloMyara isso deve ser parte da resposta, não apenas um comentário. Adicionado agora eu mesmo.
Shadow Wizard is Ear For You
Observação: esta é a resposta mais eficiente, sem funções complicadas que podem ficar muito lentas. Portanto, dei uma recompensa extra.
Shadow Wizard is Ear For You
12

Experimente isto:

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

- Por favor, olhe para estes.

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

- Espero que isso te ajude

Mr.Wimol Prommajorm
fonte
1
Disponível desde o SQL Server 2012: msdn.microsoft.com/en-us/library/hh213505.aspx
Styxxy
5

Isso funciona para strings, inteiros e numéricos:

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

Onde 4está o comprimento desejado. Funciona para números com mais de 4 dígitos, retorna uma string vazia no NULLvalor.

Piotr Nawrot
fonte
3

Se alguém ainda estiver interessado, encontrei este artigo em DATABASE.GUIDE:
Preenchimento esquerdo no SQL Server - 3 LPAD () equivalentes

Resumindo, existem 3 métodos mencionados nesse artigo.
Digamos que seu id = 12 e você precise que ele seja exibido como 0012.

Método 1 - Use a função RIGHT ()
O primeiro método usa a função RIGHT () para retornar apenas a parte mais à direita da string, após adicionar alguns zeros à esquerda.

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

Resultado:
0012

Método 2 - Use uma combinação de RIGHT () e REPLICATE ()
Este método é quase o mesmo que o método anterior, com a única diferença que eu simplesmente substituo os três zeros pela função REPLICATE ():

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

Resultado:
0012

Método 3 - Use uma combinação de REPLACE () e STR ()
Este método vem de um ângulo completamente diferente dos métodos anteriores:

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

Resultado:
0012

Confira o artigo, há uma análise mais aprofundada com exemplos.

kfed
fonte
2

É o que normalmente uso quando preciso preencher um valor.

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

Eu precisava disso em uma função no servidor SQL e ajustei um pouco a resposta de Patrick.

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
fonte
1

Criar Função:

    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

Exemplo:

Select dbo.PadLeft('123456','0',8)
mehrdad
fonte
Só uma observação sobre padrões, eu não me incomodaria com a verificação IsNull, se o valor for nulo, a função ainda deve retornar nulo para esse valor, pois esse é o comportamento padrão para as funções internas. Se convertermos tudo em um valor não nulo, o chamador não poderá mais usar operações lógicas nulas que, de outra forma, estaria esperando. (Nulo em muitas de minhas tabelas significa 'não especificado' e um valor padrão deve ser usado.SELECT @var = LTRIM(RTRIM(@Text))
Chris Schaller
1

Eu criei uma função:

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;

Use: selecione dbo.fnPadLeft (123, 10)

Retorna: 0000000123

Anne Lord
fonte
0

Algo bastante compatível com ODBC, se necessário, pode ser o seguinte:

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

Isso se baseia no fato de que a quantidade de dígitos para um número de base 10 pode ser encontrada pelo componente integral de seu log. Disto podemos subtraí-lo da largura de preenchimento desejada. A repetição retornará nullpara valores abaixo de 1, então precisamos ifnull.

Brett Ryan
fonte
0

Minha solução não é eficiente, mas me ajudou em situações em que os valores (números de cheque bancário e número de referência de transferência eletrônica) foram armazenados como varchar onde algumas entradas tinham valores alfanuméricos com eles e eu tive que preencher se o comprimento for menor que 6 caracteres.

Pensei em compartilhar se alguém se deparasse com a mesma situação

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
fonte
0

Um exemplo simples seria

    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
fonte
0

Criei uma função para fazer isso, onde você pode especificar o comprimento de caractere de saída desejado:

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

Resultados de exemplo

Jermaine
fonte
-5

A maneira mais eficiente é:

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

The result :
id
----
1
2
12
123
1234
SECUBE
fonte
6
Como isso responde à pergunta dos OPs sobre o preenchimento com zeros?
Filburt