Supprimer les zéros de fin de Décimal dans SQL Server
22 réponses
Un decimal(9,6)
magasins de 6 chiffres sur le côté droit de la virgule. Afficher ou non des zéros de fin est une décision de formatage, généralement implémentée du côté client.
Mais comme SSMS formate float
sans zéros de fin, vous pouvez supprimer les zéros de fin en convertissant le decimal
en float
:
select
cast(123.4567 as DECIMAL(9,6))
, cast(cast(123.4567 as DECIMAL(9,6)) as float)
Impressions:
123.456700 123,4567
(Mon séparateur décimal est une virgule, Mais SSMS formate décimal avec un point. Apparemment un problème 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 avec FLOAT (ou REAL): n'utilisez pas {[3] } ou plus (ou g8
ou plus avec REAL), car la précision limitée de la représentation de la machine provoque 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'
En outre, notez que, selon la documentation :
Le FORMATRepose sur la présence du langage commun. NET Framework Runtime (CLR). Cette fonction ne sera pas distant car cela dépend de la présence de la CLR. Remoting une fonction qui nécessite le CLR provoquerait une erreur sur le serveur distant.
Fonctionne aussi dans SqlAzure.
SELECT REVERSE(ROUND(REVERSE(2.5500),1))
Impressions:
2.55
J'étais réticent à lancer pour flotter en raison de la possibilité que plus de chiffres soient dans ma décimale que float peut représenter
FORMAT
lorsqu'il est utilisé avec une chaîne de format. net standard 'g8' renvoie la notation scientifique dans les cas de très petites décimales (par exemple 1e-08) Qui était également inadaptée
Utilisation d'une chaîne de format personnalisée ( https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings ) 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 vous voulez que votre numéro ait au moins un zéro final, donc 2.0 ne devient pas 2, Utilisez une chaîne de format comme 0.0#####
Le point décimal est localisé, de sorte que les cultures qui utilisent une virgule comme séparateur décimal rencontreront une sortie virgule Où le . est
Bien sûr, c'est la pratique décourageable d'avoir la couche de données en train de faire du formatage (mais dans mon cas il n'y a pas d'autre couche; l'utilisateur exécute littéralement une procédure stockée et met le résultat dans un email:/)
J'ai eu un problème similaire, mais j'étais également obligé de 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 de la chaîne décimale sur la longueur du composant fraction (sans utiliser de casse). Pour rendre les choses encore plus intéressantes, mon numéro a été 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 sais, mais je suis arrivé là, avec beaucoup d'aide de la les réponses ci-dessus.
Le meilleur moyen est de ne pas convertir en FLOAT ou MONEY avant de convertir en raison d'un risque de perte de précision. Donc, les moyens sécurisés peuvent être quelque chose comme ceci:
CREATE FUNCTION [dbo].[fn_ConvertToString]
(
@value sql_variant
)
RETURNS varchar(max)
AS
BEGIN
declare @x varchar(max)
set @x= reverse(replace(ltrim(reverse(replace(convert(varchar(max) , @value),'0',' '))),' ',0))
--remove "unneeded "dot" if any
set @x = Replace(RTRIM(Replace(@x,'.',' ')),' ' ,'.')
return @x
END
Où @valeur peut être tout décimal(x,y)
J'avais besoin de supprimer les zéros de fin sur mes décimales afin de pouvoir sortir une chaîne d'une certaine longueur avec seulement zéros
(par exemple, j'avais besoin de sortir 14 caractères pour que 142.023400 devienne 000000142.0234),
, j'ai utilisé parsename
, reverse
et cast
as int
pour supprimer les zéros de fin:
SELECT
PARSENAME(2.5500,2)
+ '.'
+ REVERSE(CAST(REVERSE(PARSENAME(2.5500,1)) as int))
(pour ensuite obtenir mes zéros principaux, je pourrais répliquer le nombre correct de zéros en fonction de la longueur de ce qui précède et concaténer ceci à l'avant du ci-dessus)
J'espère que cela aide quelqu'un.
Il est possible de supprimer les zéros de début et de fin dans TSQL
-
Convertissez-le en chaîne en utilisant la fonction STR TSQL si ce n'est pas une chaîne, alors
-
Supprimer les deux zéros de début et de fin
SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount
Plus d'infos sur forum.
Essayez ceci :
SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")
Donne 20.55
Une autre option...
Je ne sais pas à quel point c'est efficace mais cela semble fonctionner et ne passe pas par float:
select replace(rtrim(replace(
replace(rtrim(replace(cast(@value as varchar(40)), '0', ' ')), ' ', '0')
, '.', ' ')), ' ', '.')
La ligne médiane supprime les espaces de fin, les deux extérieurs suppriment le point s'il n'y a pas de chiffres décimaux
Et ç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(ltrim(rtrim(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0'), 1) = '.'
then '0'
else ''
end +
replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0') +
case when right(replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0'), 1) = '.'
then '0'
else ''
end
Je comprends que c'est un ancien post 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 de FORMAT pour une raison quelconque, alors les travaux suivants.
En outre, beaucoup de solutions ne fonctionnaient pas si le nombre était inférieur à 1 (par exemple 0.01230000).
Veuillez noter que ce qui suit ne fonctionne 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')
Renvoie respectivement 10.012345 et 0.012345.
Essayez ceci.
select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
Le plus simple est de convertir la valeur en FLOAT, puis en un type de données string.
CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100))
J'ai eu un problème similaire, nécessaire de couper les zéros de fin de 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 à rogner. Espérons que cela aide quelqu'un d'autre.
Une colonne décimale(9,6) se convertira en flottant sans perte de précision, donc CAST(... Comme float) fera l'affaire.
@HLGEM: dire que float est un mauvais choix pour stocker des nombres et "ne jamais utiliser float" n'est pas correct - il suffit de connaître vos nombres, par exemple les mesures de température iraient bien comme des flotteurs.
@abatishchev et @ japongskie: les préfixes devant les procs et les fonctions stockés par SQL sont toujours une bonne idée, si ce n'est pas nécessaire; les liens que vous avez mentionnés seulement indique 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
Essayez ceci:
select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100
Essayez ceci:
select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)