从SQL Server中的十进制中删除尾随零

我有一个列DECIMAL(9,6)即它支持的值如999,123456。

但是当我插入123,4567这样的数据时,它变成123,456700

如何删除这些零?

除非你想把它转换成一个string,否则你不能。 您需要在表示层中执行此操作。

decimal(9,6)在逗号右侧存储6位数字。 是否显示尾随零是格式化决定,通常在客户端执行。

但是由于SSMS格式的float不为零,因此可以通过将decimal转换为float来删除尾随的零:

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

打印:

 123.456700 123,4567 

(我的小数点分隔符是一个逗号,但SSMS格式小数点,显然是一个已知的问题 。)

您可以使用FORMAT()函数(SqlAzure和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' 

使用FLOAT(或REAL)时要小心:不要使用g17或更大(或g17以上的g8或更大),因为机器表示的有限精度会导致不必要的影响:

 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' 

此外,请注意,根据文件 :

FORMAT依赖于.NET Framework公共语言运行时(CLR)的存在。 这个函数不会被远程访问,因为它取决于CLR的存在。 远程处理需要CLR的函数会导致远程服务器出错。

也可以在SqlAzure中使用。

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

打印:

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

应该这样做。

我有一个类似的问题,但也被要求删除小数点不存在小数,这里是我的解决scheme,将小数分解成其组成部分,并根据小数点string的长度分数部分(不使用CASE)。 为了使事情更有趣,我的号码被存储为一个没有小数的浮点数。

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

结果是痛苦的,我知道,但我到了那里,在上面的答案很多的帮助。

我需要删除我的小数的尾随零,所以我可以输出只有前导零的一定长度的string

(例如,我需要输出14个字符,使142.023400变成000000142.0234),

我使用parsenamereverseas int去除尾随零:

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

(为了得到我的前导零,我可以根据上面的长度复制正确数量的零并连接到上面的前面)

我希望这有助于某人。

可以删除TSQL中的前导和尾随零

  1. 如果不是string,则使用STR TSQL函数将其转换为string

  2. 删除前导和尾随零

     SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount 
  3. 更多信息论坛 。

尝试这个 :

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

给20.55

在转换之前,最好的方法是不要转换为FLOATMONEY ,因为精度的损失。 所以安全的方式可以是这样的:

 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 

其中@value可以是任何小数(x,y)

另一个select…

我不知道这是多高效,但它似乎工作,并不通过浮法:

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

中间的线剥离尾随空格,如果没有小数位,则外侧的两个线删除该点

这个怎么样? 假设数据作为@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 

我明白这是一个旧的职位,但想提供SQL,我想出了

 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 

我知道这个线程是非常旧的,但对于那些不使用SQL Server 2012或更高版本,或者由于任何原因无法使用FORMAT函数,那么下面的工作。

另外,如果数量小于1(例如0.01230000),许多解决scheme都不起作用。

请注意以下内容不适用于负数。

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

分别返回10.012345和0.012345。

尝试这个。

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

最简单的方法是CAST的值FLOAT,然后到一个string数据types。

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

我有一个类似的问题,需要修剪像xx0000,x00000,xxx000数字尾随零

我用了:

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

代码是要修剪数字的字段的名称。 希望这可以帮助别人。

DECIMAL(9,6)列将转换为浮点数而不会损失精度,因此CAST(… AS float)将会执行此操作。


@HLGEM:说浮点数是一个不好的select来储存数字,“永远不使用浮点数”是不正确的 – 你只需要知道你的数字,例如温度测量就可以很好地作为浮点数。

@abatishchev和@japongskie:前面的SQL存储过程和函数的前缀仍然是一个好主意,如果不是必需的; 您提到的链接仅指示不要使用不应使用的存储过程的“sp_”前缀,其他前缀也可以,例如“usp_”或“spBob_”

参考:“所有具有6个或更less有效小数位的整数都可以转换为IEEE 754浮点值,而不会降低精度”: https : //en.wikipedia.org/wiki/Single-precision_floating-point_format

尝试这个:

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

尝试这个:

 select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)