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

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

Mais quand j'insère des données comme 123,4567, elles deviennent 123,456700

Comment supprimer ces zéros?

60
demandé sur Espo 2010-05-30 14:56:45

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 .)

110
répondu Andomar 2010-05-30 11:04:51

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 FORMAT

Repose 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.

23
répondu robert4 2017-04-08 05:18:47
SELECT CONVERT(DOUBLE PRECISION, [ColumnName])
11
répondu Bat_Programmer 2015-06-22 23:37:32
SELECT REVERSE(ROUND(REVERSE(2.5500),1))

Impressions:

2.55
7
répondu user1959416 2014-06-17 18:05:40
Cast(20.5500 as Decimal(6,2))

Devrait le faire.

3
répondu Peter Jones 2014-04-24 15:37:29

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:/)

3
répondu Caius Jard 2018-06-26 10:00:39

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.

2
répondu Adge Cutler 2014-06-03 09:30:41

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)

2
répondu Mahmoud Moravej 2014-12-12 04:37:41

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.

1
répondu Ali 2013-04-25 11:50:51

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

  1. Convertissez-le en chaîne en utilisant la fonction STR TSQL si ce n'est pas une chaîne, alors

  2. Supprimer les deux zéros de début et de fin

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

1
répondu Ishtiaq 2013-08-07 18:02:14

Essayez ceci :

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

Donne 20.55

1
répondu Todd 2013-12-18 11:25:08

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

0
répondu SQLian 2013-02-07 13:49:59

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
0
répondu MrNazgul 2013-05-31 01:32:45
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
0
répondu beloblotskiy 2013-10-14 07:15:10

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
0
répondu Abhi 2014-07-23 20:19:54

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.

0
répondu Alan Schofield 2014-12-16 13:15:52

Essayez ceci.

select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
0
répondu Vishal Kiri 2015-09-09 08:38:38

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))
0
répondu Brad Raiche 2016-06-30 15:55:24

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.

0
répondu Kazeem Muritala 2016-08-10 16:57:55

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

0
répondu Kobus 2017-06-02 09:54:43

Essayez ceci:

select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100
-1
répondu Vipin J S 2012-02-20 12:48:23

Essayez ceci:

select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)
-1
répondu kierzo 2015-11-07 22:55:53