Fonction PadLeft dans T-SQL

113

J'ai le tableau A suivant:

id
----
1
2
12
123
1234

J'ai besoin de remplir à gauche les idvaleurs avec des zéros:

id
----
0001
0002
0012
0123
1234

Comment puis-je atteindre cet objectif?

Gali
la source

Réponses:

197

Je crois que c'est peut-être ce que vous recherchez:

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

Je n'ai pas testé la syntaxe sur le 2ème exemple. Je ne sais pas si cela fonctionne à 100% - cela peut nécessiter quelques ajustements - mais cela donne l'idée générale de la façon d'obtenir la sortie souhaitée.

ÉDITER

Pour répondre aux préoccupations énumérées dans les commentaires ...

@ pkr298 - Oui STR ne fonctionne que sur les nombres ... Le champ de l'OP est un ID ... donc uniquement un nombre.

@Desolator - Bien sûr, cela ne fonctionnera pas ... le premier paramètre contient 6 caractères. Vous pouvez faire quelque chose comme:

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

cela devrait théoriquement déplacer les poteaux de but ... au fur et à mesure que le nombre augmente, il devrait TOUJOURS fonctionner .... peu importe si c'est 1 ou 123456789 ...

Donc, si votre valeur maximale est 123456 ... vous verrez 0000123456 et si votre valeur minimale est 1, vous verrez 0000000001

Patrick
la source
4
STR () ne fonctionne que sur les nombres (ou les nombres dans les champs de chaîne). Ce code est interrompu si vous l'utilisez sur un champ varchar que vous supposez avoir un nombre mais que l'un des enregistrements contient des données incorrectes (non numériques). La fonction DROITE () ne sera pas interrompue dans ce cas.
pkr298 du
1
La fonction STR () ne fonctionnera pas si le nombre est plus long (par exemple STR(123456, 4), retournera****
2
@Desolator J'ai ajouté une réponse et une correction pour faciliter le scénario que vous avez ajouté.
Patrick
66

SQL Server prend désormais en charge la fonction FORMAT à partir de la version 2012, donc:

SELECT FORMAT(id, '0000') FROM TableA

fera l'affaire.

Si votre identifiant ou votre colonne est dans a varcharet représente un nombre que vous convertissez en premier:

SELECT FORMAT(CONVERT(INT,id), '0000') FROM TableA
CrimsonKing
la source
Slick et simple, merci! Compte tenu de la date de la question initiale, cela devrait maintenant être la réponse officielle;)
David Gunderson
1
Si id est une chaîne, vous pouvez d'abord le convertir en entier - sélectionnez le format (convert (int, id), '0000')
CrimsonKing
Désolé mais je déconseille car cette façon est VRAIMENT lente. Il a fallu quatre secondes entières pour parcourir 90 lignes, alors que la réponse acceptée était instantanée. C'est un inconvénient majeur, et le FORMAT ne doit être utilisé que sur un ou deux enregistrements, max. Sinon, c'est inutile en raison de ses très mauvaises performances.
Shadow Wizard est une oreille pour vous
@ShadowWizard Je vois des performances instantanées en utilisant FORMAT avec des milliers de lignes.
JohnnyHK
@JohnnyHK bien peut-être quelque chose avec le design de la table ou d'autres bizarreries de la base de données, mais quand même ... le fait est que pour moi, c'était vraiment lent alors que l'inverse était rapide.
Shadow Wizard est une oreille pour vous
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

Résultat

----
0001
0002
0012
0123
1234
Mikael Eriksson
la source
43

Ancien message, mais peut-être que cela aide quelqu'un:

Pour terminer jusqu'à ce qu'il se termine par 4 caractères non vides:

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

Pour terminer jusqu'à 10:

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

Dans le cas où la colonne est numérique , convertissez-la d'abord en varchar avec un tel code:

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

Et pour terminer jusqu'à 10 avec un champ numérique:

SELECT RIGHT ('0000000000'+Convert(nvarchar(20), COLUMNNAME), 10) FROM TABLENAME;
Marcelo Myara
la source
1
@ SilverM-A, il n'y a aucun utilitaire pour ajouter des 0 avant un nombre, car ils seront de toute façon ignorés (0003 vaut 3 après tout). Ce que vous voulez probablement accomplir est de convertir ce nombre en une chaîne (varchar), puis d'utiliser l'instruction ci-dessus.
Marcelo Myara
1
@ SilverM-A, si tel est le cas, lancez-le simplement en utilisant la commande "CAST" comme: SELECT RIGHT ('0000000000' + CAST (COLUMNNAME AS VARCHAR), 10) FROM TABLENAME; Est-ce que c'est ça?
Marcelo Myara
@MarceloMyara cela devrait faire partie de la réponse, pas seulement un commentaire. Ajouté maintenant moi-même.
Shadow Wizard est une oreille pour vous
Remarque: c'est la réponse la plus efficace, sans fonctions sophistiquées qui pourraient devenir très lentes. Par conséquent, je lui ai donné une prime supplémentaire.
Shadow Wizard est une oreille pour vous
12

Essaye ça:

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

- Veuillez les examiner.

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

- J'espère que cela vous aidera

Monsieur Wimol Prommajorm
la source
1
Disponible depuis SQL Server 2012: msdn.microsoft.com/en-us/library/hh213505.aspx
Styxxy
5

Cela fonctionne pour les chaînes, les entiers et les nombres:

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

4est la longueur souhaitée. Fonctionne pour les nombres de plus de 4 chiffres, renvoie une chaîne vide sur la NULLvaleur.

Piotr Nawrot
la source
3

Si quelqu'un est toujours intéressé, j'ai trouvé cet article sur DATABASE.GUIDE:
Left Padding in SQL Server - 3 LPAD () Equivalents

En bref, il existe 3 méthodes mentionnées dans cet article.
Disons que votre id = 12 et que vous en avez besoin pour s'afficher sous la forme 0012.

Méthode 1 - Utilisez la fonction RIGHT ()
La première méthode utilise la fonction RIGHT () pour renvoyer uniquement la partie la plus à droite de la chaîne, après avoir ajouté quelques zéros non significatifs.

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

Résultat:
0012

Méthode 2 - Utilisez une combinaison de RIGHT () et REPLICATE ()
Cette méthode est presque la même que la méthode précédente, à la seule différence que je remplace simplement les trois zéros par la fonction REPLICATE ():

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

Résultat:
0012

Méthode 3 - Utiliser une combinaison de REPLACE () et STR ()
Cette méthode vient d'un angle complètement différent des méthodes précédentes:

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

Résultat:
0012

Consultez l'article, il y a une analyse plus approfondie avec des exemples.

kfed
la source
2

C'est ce que j'utilise normalement lorsque j'ai besoin de compléter une valeur.

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

J'en avais besoin dans une fonction sur le serveur SQL et j'ai ajusté un peu la réponse 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
la source
1

Créer une fonction:

    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

Exemple:

Select dbo.PadLeft('123456','0',8)
mehrdad
la source
Juste un point sur les normes, je ne me soucierais pas de la vérification IsNull, si la valeur est nulle, la fonction devrait toujours renvoyer null pour cette valeur car il s'agit du comportement standard des fonctions intégrées. Si nous convertissons tout en une valeur non nulle, l'appelant ne pourra plus utiliser les opérations logiques nulles auxquelles il pourrait autrement s'attendre. (Null dans beaucoup de mes tableaux signifie «non spécifié» et une valeur par défaut doit être utilisée.SELECT @var = LTRIM(RTRIM(@Text))
Chris Schaller
1

J'ai créé une fonction:

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;

Utilisation: sélectionnez dbo.fnPadLeft (123, 10)

Renvoie: 0000000123

Anne Lord
la source
0

Quelque chose d'assez conforme ODBC si nécessaire peut être le suivant:

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

Ceci repose sur le fait que la quantité de chiffres pour un nombre en base 10 peut être trouvée par la composante intégrale de son journal. De cela, nous pouvons le soustraire de la largeur de remplissage souhaitée. Repeat retournera nullpour les valeurs inférieures à 1, nous en avons donc besoin ifnull.

Brett Ryan
la source
0

Ma solution n'est pas efficace mais m'a aidé dans une situation où les valeurs (numéros de chèque bancaire et numéro de virement bancaire) étaient stockées en tant que varchar où certaines entrées avaient des valeurs alphanumériques avec elles et je devais compléter si la longueur est inférieure à 6 caractères.

Pensé pour partager si quelqu'un rencontre la même situation

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
la source
0

Un exemple simple serait

    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
la source
0

J'ai créé une fonction pour ce faire, où vous pouvez spécifier la longueur de caractère de sortie souhaitée:

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

Exemple de résultats

Jermaine
la source
-5

Un moyen plus efficace est:

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

The result :
id
----
1
2
12
123
1234
SECUBE
la source
6
Comment cela répond-il à la question des OP sur le remplissage avec des zéros?
Filburt