Suppression des zéros non significatifs d'un champ dans une instruction SQL


99

Je travaille sur une requête SQL qui lit à partir d'une base de données SQLServer pour produire un fichier d'extrait. L'une des conditions requises pour supprimer les zéros non significatifs d'un champ particulier, qui est un VARCHAR(10)champ simple . Ainsi, par exemple, si le champ contient «00001A», l'instruction SELECT doit renvoyer les données sous la forme «1A».

Existe-t-il un moyen en SQL de supprimer facilement les zéros non significatifs de cette manière? Je sais qu'il existe une RTRIMfonction, mais cela ne semble supprimer que des espaces.


3
En guise de vote favorable à la réponse stackoverflow.com/a/11129399/1635441 de David Walker , veuillez vous référer à la réponse d'Arvo publiée: stackoverflow.com/a/662437/1635441
ramizmoh

Réponses:


152
select substring(ColumnName, patindex('%[^0]%',ColumnName), 10)

8
Cela posera des problèmes lorsque la chaîne est entièrement composée de "0", car elle ne correspondra jamais à un caractère non "0".
Cade Roux

Vrai. Dans ce cas, il renverra toute la chaîne de zéros non modifiée. Si cela pose un problème, la valeur de retour de patindex devra être testée par rapport à zéro.
Ian Horwill

@Zapnologica: Non. Vous devrez le mettre dans une instruction "update TableName set ColumnName = ...".
Ian Horwill

Bien sûr, si vous utilisez des instructions de mise à jour.
Srivastav

1
Avant d'utiliser cette solution, veuillez essayer de regarder la réponse d'Arvo publiée ici
OscarSosa

27
select replace(ltrim(replace(ColumnName,'0',' ')),' ','0')

J'ai reçu "La fonction de remplacement nécessite 3 arguments." Je crois qu'il devrait lire select replace (ltrim (replace (ColumnName, '0', ``)), '', '0')
brentlightsey

5
Cela échouera si la valeur contient un espace. Exemple: "0001 B" doit devenir "1 B" mais deviendra "10B" à la place.
Omaer

1
Comme @Omaer l'a mentionné, ce n'est pas sûr s'il y a des espaces dans la chaîne. Solution améliorée - remplacez d'abord les espaces par des caractères qui sont peu susceptibles d'entrer en entrée, et après 0-ltrim, restaurez ces caractères dans les espaces après. En fin de compte, cela semble assez complexe :( Exemple: select replace (replace (ltrim (replace (replace ('000309933200,00 USD', '', '|'), '0', '')), '', '0 '),' | ',' ') -> 309933200,00 USD
Robert Lujo

5
select substring(substring('B10000N0Z', patindex('%[0]%','B10000N0Z'), 20), 
    patindex('%[^0]%',substring('B10000N0Z', patindex('%[0]%','B10000N0Z'), 
    20)), 20)

les retours N0Z, c'est-à-dire se débarrasser des zéros non significatifs et de tout ce qui les précède.


5
Comment est-ce un 0 si quelque chose vient avant?
xxbbcc

4

J'avais le même besoin et j'ai utilisé ceci:

select 
    case 
        when left(column,1) = '0' 
        then right(column, (len(column)-1)) 
        else column 
      end

3

Si vous souhaitez que la requête renvoie un 0 au lieu d'une chaîne de zéros ou de toute autre valeur, vous pouvez le transformer en une instruction case comme celle-ci:

select CASE
      WHEN ColumnName = substring(ColumnName, patindex('%[^0]%',ColumnName), 10) 
       THEN '0'
      ELSE substring(ColumnName, patindex('%[^0]%',ColumnName), 10) 
      END

2

Vous pouvez utiliser ceci:

SELECT REPLACE(LTRIM(REPLACE('000010A', '0', ' ')),' ', '0')

0

Vous pouvez essayer ceci - il prend un soin particulier de ne supprimer que les zéros non significatifs si nécessaire:

DECLARE @LeadingZeros    VARCHAR(10) ='-000987000'

SET @LeadingZeros =
      CASE WHEN PATINDEX('%-0', @LeadingZeros) = 1   THEN 
           @LeadingZeros
      ELSE 
           CAST(CAST(@LeadingZeros AS INT) AS VARCHAR(10)) 
      END   

SELECT @LeadingZeros

Ou vous pouvez simplement appeler

CAST(CAST(@LeadingZeros AS INT) AS VARCHAR(10)) 

0

Voici la fonction de valeur scalaire SQL qui supprime les zéros non significatifs de la chaîne:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Vikas Patel
-- Create date: 01/31/2019
-- Description: Remove leading zeros from string
-- =============================================
CREATE FUNCTION dbo.funRemoveLeadingZeros 
(
    -- Add the parameters for the function here
    @Input varchar(max)
)
RETURNS varchar(max)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @Result varchar(max)

    -- Add the T-SQL statements to compute the return value here
    SET @Result = @Input

    WHILE LEFT(@Result, 1) = '0'
    BEGIN
        SET @Result = SUBSTRING(@Result, 2, LEN(@Result) - 1)
    END

    -- Return the result of the function
    RETURN @Result

END
GO


-1

Supprimer le 0 de début du mois suivant la déclaration fonctionnera certainement.

SELECT replace(left(Convert(nvarchar,GETDATE(),101),2),'0','')+RIGHT(Convert(nvarchar,GETDATE(),101),8) 

Remplacez simplement GETDATE()par le champ de date de votre table.


3
Comment cela répond-il exactement à la question?
deutschZuid

-2

tu peux essayer ça SELECT REPLACE(columnname,'0','') FROM table


3
Cela supprimera 0 quelle que soit sa position. La question ne concerne que les principaux.
Dimanche

-2

Pour supprimer le premier 0, vous pouvez multiplier la colonne numérique par 1 Par exemple: Sélectionnez (ColumnName * 1)


3
Que signifie «1A» * 1?
Jonathan Rys

qu'est-ce que 10 * 1 sera?
RATAN KUMAR

Il a été indiqué dans la question que le type de colonne est VARCHAR (10), donc la multiplication n'est pas possible.
y434y

-2
select replace(replace(rtrim(replace(replace(replace(replace(ltrim(replace(replace([COLUMN],' ','[Ltrim]'),[Ltrim],' ')),' ',[Ltrim]),'[Ltrim]',' '),' ','[Rtrim]'),[Rtrim],' ')),' ',[Rtrim]),'[Rtrim]',' ') As Result

Il s'agit d'un script Sql qui émule la fonctionnalité de la commande TRIM dans tsql avant 2017, c'est fondamentalement le même que les autres recommandations, mais les autres remplacent par un seul caractère inhabituel qui peut encore se produire, «[Rtrim]» ou «[ Ltrim] 'pouvait toujours apparaître dans le texte, mais remplacer hat par un texte unique, par exemple un Guid, résoudrait ce problème.

je ne l'ai pas testé concernant la vitesse


-3

J'ai emprunté aux idées ci-dessus. Ce n'est ni rapide ni élégant. mais c'est exact.

CAS

WHEN left(column, 3) = '000' THEN right(column, (len(column)-3))

WHEN left(column, 2) = '00' THEN right(a.column, (len(column)-2))

WHEN left(column, 1) = '0' THEN right(a.column, (len(column)-1))

ELSE 

FIN


Il n'est pas non plus dynamique de permettre plus de 3 zéros.
JoeFletch

-3
select CASE
         WHEN TRY_CONVERT(bigint,Mtrl_Nbr) = 0
           THEN ''
           ELSE substring(Mtrl_Nbr, patindex('%[^0]%',Mtrl_Nbr), 18)
       END

1
Vous devez donner une explication avec vos réponses, pas seulement un seul extrait de code. Veuillez également formater le code sous forme de code (il y a un bouton en haut de la zone de saisie de texte).
David Heyman

-4
select ltrim('000045', '0') from dual;

LTRIM
-----
45

Cela devrait faire l'affaire.


2
Il n'y a pas de surcharge pour le serveur SQL.
BillRob

Dans PostgreSQL, il suffit d'écrire select trim(leading '0' from '001A');, mais OP demandait SQL Server.
y434y
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.