Supprimer les zéros de fin de décimal dans SQL Server

J’ai une colonne DECIMAL(9,6) c’est-à-dire qu’elle supporte des valeurs comme 999,123456.

Mais quand j’insère des données comme 123,4567, il devient 123,456700

Comment supprimer ces zéros?

Une decimal(9,6) stocke 6 chiffres du côté droit de la virgule. Le fait d’afficher ou non les zéros de fin est une décision de mise en forme, généralement implémentée du côté client.

Mais comme les formats SSMS float sans les zéros de fin, vous pouvez supprimer les zéros de fin en convertissant la decimal en valeur float :

 select cast(123.4567 as DECIMAL(9,6)) , cast(cast(123.4567 as DECIMAL(9,6)) as float) 

estampes:

 123.456700 123,4567 

(Mon séparateur décimal est une virgule, mais SSMS formate un nombre décimal avec un point. Apparemment, un problème est connu .)

Vous pouvez utiliser la fonction FORMAT() (SqlAzure et Sql Server 2012+):

 SELECT FORMAT(CAST(15.12 AS DECIMAL(9,6)), 'g18') -- '15.12' SELECT FORMAT(CAST(0.0001575 AS DECIMAL(9,6)), 'g10') -- '0.000158' SELECT FORMAT(CAST(2.0 AS DECIMAL(9,6)), 'g15') -- '2' 

Soyez prudent lorsque vous utilisez FLOAT (ou REAL): n’utilisez pas g17 ou supérieur (ou g8 ou plus grand avec REAL), car la précision limitée de la représentation de la machine entraîne des effets indésirables:

 SELECT FORMAT(CAST(15.12 AS FLOAT), 'g17') -- '15.119999999999999' SELECT FORMAT(CAST(0.9 AS REAL), 'g8') -- '0.89999998' SELECT FORMAT(CAST(0.9 AS REAL), 'g7') -- '0.9' 

De plus, notez que, selon la documentation :

FORMAT repose sur la présence du CLR (Common Language Runtime) .NET Framework. Cette fonction ne sera pas déscope car elle dépend de la présence du CLR. Remoter une fonction nécessitant le CLR provoquerait une erreur sur le serveur distant.

Fonctionne également dans SqlAzure.

 SELECT CONVERT(DOUBLE PRECISION, [ColumnName]) 
 SELECT REVERSE(ROUND(REVERSE(2.5500),1)) 

estampes:

 2.55 
 Cast(20.5500 as Decimal(6,2)) 

devrait le faire.

J’avais un problème similaire, mais je devais également supprimer le point décimal où aucune décimale n’était présente, voici ma solution qui divise la décimale en ses composants et base le nombre de caractères qu’il prend sur la longueur de la chaîne décimale. le composant fraction (sans utiliser CASE). Pour rendre les choses encore plus intéressantes, mon numéro était stocké comme un flotteur sans ses décimales.

 DECLARE @MyNum FLOAT SET @MyNum = 700000 SELECT CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),2) AS VARCHAR(10)) + SUBSTRING('.',1,LEN(REPLACE(RTRIM(REPLACE(CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),1) AS VARCHAR(2)),'0',' ')),' ','0'))) + REPLACE(RTRIM(REPLACE(CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),1) AS VARCHAR(2)),'0',' ')),' ','0') 

Le résultat est douloureux, je le sais, mais je suis arrivé avec beaucoup d’aide grâce aux réponses ci-dessus.

Le meilleur moyen n’est PAS de convertir en FLOAT ou en MONEY avant la conversion en raison des risques de perte de précision. Donc, les moyens sécurisés peuvent être quelque chose comme ceci:

 CREATE FUNCTION [dbo].[fn_ConvertToSsortingng] ( @value sql_variant ) RETURNS varchar(max) AS BEGIN declare @x varchar(max) set @x= reverse(replace(lsortingm(reverse(replace(convert(varchar(max) , @value),'0',' '))),' ',0)) --remove "unneeded "dot" if any set @x = Replace(RTRIM(Replace(@x,'.',' ')),' ' ,'.') return @x END 

où @value peut être n’importe quel décimal (x, y)

J’étais réticent à lancer pour flotter en raison de la possibilité que plus de chiffres soient dans mon nombre décimal que flottant peut représenter

FORMAT lorsqu’il est utilisé avec une chaîne de format standard .net ‘g8’ a renvoyé la notation scientifique en cas de très petites décimales (par exemple, 1e-08), ce qui n’était

L’utilisation d’une chaîne de format personnalisée ( https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-ssortingngs ) m’a permis de réaliser ce que je voulais:

 DECLARE @n DECIMAL(9,6) =1.23; SELECT @n --> 1.230000 SELECT FORMAT(@n, '0.######') --> 1.23 

Si vous voulez que votre numéro ait au moins un zéro final, alors 2.0 ne devienne pas 2, utilisez une chaîne de format comme 0.0#####

Le point décimal est localisé, donc les cultures qui utilisent une virgule comme séparateur décimal rencontreront une virgule où le. est

Bien sûr, c’est la pratique décourageante d’avoir la couche de données en forme (mais dans mon cas il n’y a pas d’autre couche, l’utilisateur exécute littéralement une procédure stockée et place le résultat dans un email: /)

J’avais besoin de supprimer les zéros de fin sur mes décimales pour pouvoir sortir une chaîne d’une certaine longueur avec uniquement des zéros en tête

(par exemple, je devais afficher 14 caractères pour que 142.023400 devienne 000000142.0234),

J’ai utilisé parsename , reverse et cast as int pour supprimer les zéros à la fin:

 SELECT PARSENAME(2.5500,2) + '.' + REVERSE(CAST(REVERSE(PARSENAME(2.5500,1)) as int)) 

(Pour obtenir ensuite mes zéros de tête, je pourrais reproduire le nombre correct de zéros en fonction de la longueur de ce qui précède et concaténer ceci au début de la précédente)

J’espère que cela aide quelqu’un.

il est possible de supprimer les zéros de début et de fin dans TSQL

  1. Convertissez-le en chaîne à l’aide de la fonction STR TSQL si ce n’est pas de la chaîne, alors

  2. Supprimer les deux zéros avant et arrière

     SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount 
  3. Plus d’infos sur le forum .

Essaye ça :

 SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0") 

Donne 20,55

Une autre option…

Je ne sais pas à quel point cela est efficace, mais cela semble fonctionner et ne passe pas par le flottant:

 select replace(rsortingm(replace( replace(rsortingm(replace(cast(@value as varchar(40)), '0', ' ')), ' ', '0') , '.', ' ')), ' ', '.') 

La ligne médiane dépouille les espaces de fin, les deux autres retirent le point s’il n’y a pas de chiffres décimaux

Que dis-tu de ça? En supposant que les données entrent dans votre fonction en tant que @thisData:

 BEGIN DECLARE @thisText VARCHAR(255) SET @thisText = REPLACE(RTRIM(REPLACE(@thisData, '0', ' ')), ' ', '0') IF SUBSTRING(@thisText, LEN(@thisText), 1) = '.' RETURN STUFF(@thisText, LEN(@thisText), 1, '') RETURN @thisText END 
 case when left(replace(lsortingm(rsortingm(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0'), 1) = '.' then '0' else '' end + replace(lsortingm(rsortingm(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0') + case when right(replace(lsortingm(rsortingm(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0'), 1) = '.' then '0' else '' end 

Je comprends que c’est un ancien message, mais je voudrais fournir SQL que j’ai trouvé

 DECLARE @value DECIMAL(23,3) set @value = 1.2000 select @value original_val, SUBSTRING( CAST( @value as VARCHAR(100)), 0, PATINDEX('%.%',CAST(@value as VARCHAR(100))) ) + CASE WHEN ROUND( REVERSE( SUBSTRING( CAST(@value as VARCHAR(100)), PATINDEX('%.%',CAST(@value as VARCHAR(100)))+1, LEN(CAST(@value as VARCHAR(100))) ) ) ,1) > 0 THEN '.' + REVERSE(ROUND(REVERSE(SUBSTRING( CAST(@value as VARCHAR(100)), PATINDEX('%.%',CAST(@value as VARCHAR(100)))+1, LEN(CAST(@value as VARCHAR(100))) ) ),1)) ELSE '' END AS modified_val 

Je sais que ce thread est très ancien mais pour ceux qui n’utilisent pas SQL Server 2012 ou supérieur ou ne peuvent pas utiliser la fonction FORMAT pour une raison quelconque, alors les travaux suivants.

De plus, beaucoup de solutions ne fonctionnaient pas si le nombre était inférieur à 1 (par exemple, 0,01230000).

Veuillez noter que les éléments suivants ne fonctionnent pas avec des nombres négatifs.

 DECLARE @num decimal(28,14) = 10.012345000 SELECT PARSENAME(@num,2) + REPLACE(RTRIM(LTRIM(REPLACE(@num-PARSENAME(@num,2),'0',' '))),' ','0') set @num = 0.0123450000 SELECT PARSENAME(@num,2) + REPLACE(RTRIM(LTRIM(REPLACE(@num-PARSENAME(@num,2),'0',' '))),' ','0') 

Retourne 10.012345 et 0.012345 respectivement.

essaye ça.

 select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float) 

Le moyen le plus simple est de convertir la valeur en FLOAT puis en un type de données de type chaîne.

 CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100)) 

J’ai eu un problème similaire, nécessaire pour réduire les zéros à la fin des nombres comme xx0000,x00000,xxx000

J’ai utilisé:

 select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename 

Code est le nom du champ avec le numéro à découper. J’espère que ceci aide quelqu’un d’autre.

Une colonne DECIMAL (9,6) sera convertie en float sans perte de précision, donc CAST (… AS float) fera l’affaire.


@HLGEM: dire que float est un mauvais choix pour stocker des nombres et que “Never use float” n’est pas correct – il suffit de connaître vos chiffres, par exemple les mesures de température iraient bien comme des flottants.

@abatishchev et @japongskie: les préfixes devant les procédures et les fonctions stockées SQL sont toujours une bonne idée, sinon obligatoire; les liens que vous avez mentionnés n’indiquent que de ne pas utiliser le préfixe “sp_” pour les procédures stockées que vous ne devriez pas utiliser, les autres préfixes sont corrects, par exemple “usp_” ou “spBob_”

Référence: “Tous les entiers avec 6 chiffres décimaux significatifs ou moins peuvent être convertis en une valeur à virgule flottante IEEE 754 sans perte de précision”: https://en.wikipedia.org/wiki/Single-precision_floating-point_format

Essaye ça:

 select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100 

Essaye ça:

 select isnull(cast(floor(replace(rsortingm(lsortingm('999,999.0000')),',','')) as int),0)