Función PadLeft en T-SQL

113

Tengo la siguiente tabla A:

id
----
1
2
12
123
1234

Necesito rellenar los idvalores con ceros a la izquierda :

id
----
0001
0002
0012
0123
1234

¿Cómo puedo conseguir esto?

Gali
fuente

Respuestas:

197

Creo que esto puede ser lo que estás buscando:

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

FROM tableA

o

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

FROM tableA

No he probado la sintaxis en el segundo ejemplo. No estoy seguro de si eso funciona al 100%, puede requerir algunos ajustes, pero transmite la idea general de cómo obtener el resultado deseado.

EDITAR

Para abordar las preocupaciones enumeradas en los comentarios ...

@ pkr298 - Sí, STR solo funciona con números ... El campo del OP es una ID ... por lo tanto, solo un número.

@Desolator - Por supuesto que no funcionará ... el primer parámetro tiene 6 caracteres. Puedes hacer algo como:

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

esto teóricamente debería mover los postes de la portería ... a medida que el número aumenta, SIEMPRE debería funcionar ... sin importar si es 1 o 123456789 ...

Entonces, si su valor máximo es 123456 ... verá 0000123456 y si su valor mínimo es 1, verá 0000000001

Patricio
fuente
4
STR () solo funciona con números (o números en campos de cadena). Este código se rompe si lo está usando en un campo varchar que asume que tiene un número, pero uno de los registros tiene datos incorrectos (no numéricos). La función DERECHA () no se interrumpirá en este caso.
pkr298
1
La función STR () no funcionará si el número tiene una longitud mayor (por ejemplo STR(123456, 4), volverá****
2
@Desolator He agregado una respuesta y una solución para facilitar el escenario que agregó.
Patrick
66

SQL Server ahora admite la función FORMAT a partir de la versión 2012, por lo que:

SELECT FORMAT(id, '0000') FROM TableA

hará el truco.

Si su identificación o columna está en un varchar y representa un número que convierte primero:

SELECT FORMAT(CONVERT(INT,id), '0000') FROM TableA
Rey carmesí
fuente
¡Elegante y simple, gracias! Dada la fecha de la pregunta original, esta debería ser ahora la respuesta oficial;)
David Gunderson
1
Si id es una cadena, primero puede convertirla a un número entero: seleccione el formato (convertir (int, id), '0000')
CrimsonKing
Lo siento, pero voto en contra porque esta forma es REALMENTE lenta. Tomó cuatro segundos completos para ejecutar más de 90 filas, mientras que la respuesta aceptada fue instantánea. Este es un inconveniente muy importante y el FORMATO solo debe usarse en uno o dos registros, como máximo. De lo contrario, es inútil debido a su muy bajo rendimiento.
Shadow Wizard es tu oreja
@ShadowWizard Veo un rendimiento instantáneo usando FORMAT con miles de filas.
JohnnyHK
@JohnnyHK bueno, tal vez algo con el diseño de la tabla u otras peculiaridades de la base de datos, pero aún así ... el hecho es que para mí fue muy lento, mientras que al revés fue rápido.
Shadow Wizard es el oído para ti
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
fuente
43

Publicación anterior, pero tal vez esto ayude a alguien:

Para completar hasta terminar con 4 caracteres que no estén en blanco:

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

Para completar hasta las 10:

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

En caso de que la columna sea numérica , conviértala a varchar primero con dicho código:

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

Y para completar hasta el 10 con un campo numérico:

SELECT RIGHT ('0000000000'+Convert(nvarchar(20), COLUMNNAME), 10) FROM TABLENAME;
Marcelo Myara
fuente
1
@ SilverM-A, no hay ninguna utilidad para agregar ceros antes de un número, ya que serán ignorados de todos modos (0003 es 3 después de todo). Probablemente lo que quiere lograr es convertir ese número en una cadena (varchar) y luego usar la declaración anterior.
Marcelo Myara
1
@ SilverM-A, si ese es el caso, simplemente conviértalo utilizando el comando "CAST" como: SELECT RIGHT ('0000000000' + CAST (COLUMNNAME AS VARCHAR), 10) FROM TABLENAME; ¿Es asi?
Marcelo Myara
@MarceloMyara esto debería ser parte de la respuesta, no solo un comentario. Agregué ahora yo mismo.
Shadow Wizard es tu oído
Nota: esta es la respuesta más eficiente, sin funciones sofisticadas que puedan volverse muy lentas. Por eso le he dado una recompensa extra.
Shadow Wizard es Ear For You
12

Prueba esto:

SELECT RIGHT(REPLICATE('0',4)+CAST(Id AS VARCHAR(4)),4) FROM [Table A]
aporía
fuente
8

- Por favor, mire estos.

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

- espero que estos te ayuden

Señor Wimol Prommajorm
fuente
1
Disponible desde SQL Server 2012: msdn.microsoft.com/en-us/library/hh213505.aspx
Styxxy
5

Esto funciona para cadenas, enteros y numéricos:

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

Donde 4es la longitud deseada. Funciona para números con más de 4 dígitos, devuelve una cadena vacía en el NULLvalor.

Piotr Nawrot
fuente
3

Si alguien todavía está interesado, encontré este artículo en DATABASE.GUIDE:
Left Padding in SQL Server - 3 LPAD () Equivalents

En resumen, hay 3 métodos mencionados en ese artículo.
Digamos que su id = 12 y necesita que se muestre como 0012.

Método 1: use la función RIGHT ()
El primer método usa la función RIGHT () para devolver solo la parte más a la derecha de la cadena, después de agregar algunos ceros a la izquierda.

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

Resultado:
0012

Método 2: use una combinación de RIGHT () y REPLICATE ()
Este método es casi el mismo que el método anterior, con la única diferencia de que simplemente reemplazo los tres ceros con la función REPLICATE ():

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

Resultado:
0012

Método 3: use una combinación de REPLACE () y STR ()
Este método proviene de un ángulo completamente diferente a los métodos anteriores:

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

Resultado:
0012

Consulte el artículo, hay un análisis más profundo con ejemplos.

kfed
fuente
2

Esto es lo que normalmente uso cuando necesito rellenar un valor.

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

Necesitaba esto en una función en el servidor SQL y ajusté un poco la respuesta 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
fuente
1

Crear función:

    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

Ejemplo:

Select dbo.PadLeft('123456','0',8)
mehrdad
fuente
Solo un punto sobre los estándares, no me molestaría con la verificación IsNull, si el valor es nulo, la función aún debería devolver nulo para ese valor, ya que este es el comportamiento estándar para las funciones integradas. Si convertimos todo a un valor no nulo, la persona que llama ya no podrá utilizar operaciones lógicas nulas que de otro modo podrían estar esperando. (Nulo en muchas de mis tablas significa 'no especificado' y se debe usar un valor predeterminado.SELECT @var = LTRIM(RTRIM(@Text))
Chris Schaller
1

Creé una función:

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;

Uso: seleccione dbo.fnPadLeft (123, 10)

Devoluciones: 0000000123

Anne Lord
fuente
0

Algo bastante compatible con ODBC, si es necesario, podría ser lo siguiente:

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

Esto se basa en el hecho de que la cantidad de dígitos para un número de base 10 se puede encontrar por el componente integral de su registro. De esto podemos restarlo del ancho de relleno deseado. La repetición devolverá los nullvalores por debajo de 1, por lo que necesitamos ifnull.

Brett Ryan
fuente
0

Mi solución no es eficiente, pero me ayudó en una situación en la que los valores (números de cheque bancario y número de referencia de transferencia bancaria) se almacenaron como varchar, donde algunas entradas tenían valores alfanuméricos y tuve que rellenar si la longitud es menor a 6 caracteres.

Pensado para compartir si alguien se encuentra en la misma situación.

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

Un ejemplo simple sería

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

Creé una función para hacer esto, donde puede especificar la longitud de caracteres de salida deseada:

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 ejemplo

Jermaine
fuente
-5

La forma más eficiente es:

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

The result :
id
----
1
2
12
123
1234
SECUBE
fuente
6
¿Cómo responde esto a la pregunta de los OP sobre el relleno con ceros?
Filburt