簡體   English   中英

從 SQL 服務器中的十進制中刪除尾隨零

[英]Remove trailing zeros from decimal in SQL Server

我有一列DECIMAL(9,6) ,即它支持像 999,123456 這樣的值。

但是當我插入像 123,4567 這樣的數據時,它變成了 123,456700

如何刪除那些零?

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或更大(或g8或更大與 REAL),因為機器表示的有限精度會導致不必要的影響:

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。

我不願意轉換為浮點數,因為小數點中的數字可能多於浮點數所能表示的數字

FORMAT與標准 .net 格式字符串 'g8' 一起使用時,在非常小的小數(例如 1e-08)的情況下返回科學記數法,這也是不合適的

使用自定義格式字符串( https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings )使我能夠實現我想要的:

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

如果您希望您的數字至少有一個尾隨零,因此 2.0 不會變成 2,請使用像0.0#####這樣的格式字符串

小數點是本地化的,因此使用逗號作為小數點分隔符的文化將遇到逗號輸出,其中 .

當然,這是讓數據層進行格式化的令人沮喪的做法(但在我的情況下沒有其他層;用戶實際上是在運行存儲過程並將結果放入電子郵件中:/)

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

印刷:

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

應該這樣做。

嘗試這個 :

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

給 20.55

我有一個類似的問題,但也需要刪除不存在小數點的小數點,這是我的解決方案,它將小數點拆分為其組成部分,並將小數點字符串中的字符數基於分數分量(不使用 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') 

結果很痛苦,我知道,但我在上面的答案中得到了很大幫助。

最好的方法是在轉換之前不要轉換為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)

我有一個類似的問題,需要從像xx0000,x00000,xxx000這樣的數字中修剪尾隨零

我用了:

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

代碼是帶有要修剪的數字的字段的名稱。 希望這對其他人有幫助。

另外一個選項...

我不知道這有多有效,但它似乎有效並且不通過浮動:

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

中間一行去掉尾隨空格,如果沒有十進制數字,外面的兩行去掉點

zeros我需要刪除小數上的尾隨零,這樣我就可以輸出一個只有零的特定長度的字符串

(例如,我需要輸出 14 個字符,以便 142.023400 變為 000000142.0234),

我使用parsenamereversecast as int來刪除尾隨零:

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

(為了得到我的前導零,我可以根據上面的長度復制正確數量的零並將其連接到上面的前面)

我希望這對某人有幫助。

可以刪除 TSQL 中的前導零和尾隨零

  1. 如果不是字符串,則使用 STR TSQL 函數將其轉換為字符串,然后

  2. 刪除前導零和尾隨零

    SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount
  3. 論壇上的更多信息。

這個怎么樣? 假設數據作為@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

嘗試這個。

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

最簡單的方法是將值轉換為 FLOAT,然后轉換為字符串數據類型。

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

在上述所有答案中,我發現只有兩個真正有效。 不要轉換為浮點數,這里證明如果這樣做,3.175 將不起作用。

SELECT  round(cast(3.175 as float), 2) as roundingcheck,    
CASE WHEN
    round(cast(3.175 as float), 2) = 3.18 THEN 'PASSED' ELSE 'FAILED' END
    as roundecheck,     
    CAST(round(TRY_CONVERT(DECIMAL(28,2), cast(3.175 as
    float)), 2) as nvarchar(max)) as roundconvert,  
    round(CAST(3.175 as DECIMAL(18,10)), 4) as check1,  
cast(CAST(round(CAST(3.175 as DECIMAL(18,10)), 4) as decimal(18,2)) as nvarchar(max))  as
    roundconvert2,  
cast(CAST(CAST(3.175 as DECIMAL(18,10)) as decimal(18,2)) as nvarchar(max))  as roundconvert3,
cast(CAST(CAST(3.149 as DECIMAL(18,10)) as decimal(18,1)) as nvarchar(max))  as roundconvert4,  
cast(FORMAT(round(CAST(3.175 as
    DECIMAL(18,10)), 2), '0.######') as nvarchar(max))  as roundconvert5

結果:

3.17    FAILED  3.17    3.1750000000    3.18    3.18    3.1    3.18

工作答案:

  • 如果要同時四舍五入到小數點后兩位,請使用以下命令:

     cast(CAST(CAST(3.175 as DECIMAL(18,10)) as decimal(18,2)) as nvarchar(max)) as roundconvert3,
  • 如果您不知道將有多少個小數,您可以使用它並在需要時將其與 round 一起使用:

     cast(FORMAT(round(CAST(3.175 as DECIMAL(18,10)), 2), '0.######') as nvarchar(max))

只需進入您的骨架並將您需要的值更改為浮點值。

當我將 long deicmals 轉換為 nvarchar 時,我使用轉換為雙精度並轉換為 nvarchar

SELECT CAST(CONVERT(DOUBLE PRECISION, 1.234567000000) as nvarchar(255))

Output:

1.23457

我知道這個線程很舊,但是對於那些不使用 SQL Server 2012 或更高版本或由於任何原因無法使用 FORMAT 函數的人,以下方法有效。

此外,如果數字小於 1(例如 0.01230000),許多解決方案都不起作用。

請注意,以下不適用於負數。

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 isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)

DECIMAL(9,6) 列將轉換為浮點數而不會損失精度,因此 CAST(... AS float) 可以解決問題。


@HLGEM:說浮點數對於存儲數字來說是一個糟糕的選擇,“永遠不要使用浮點數”是不正確的——你只需要知道你的數字,例如溫度測量會很好地作為浮點數。

@abatishchev 和 @japongskie:如果不需要,SQL 存儲過程和函數前面的前綴仍然是一個好主意; 您提到的鏈接僅指示不要對不應使用的存儲過程使用“sp_”前綴,其他前綴也可以,例如“usp_”或“spBob_”

參考:“所有具有 6 個或更少有效十進制數字的整數都可以轉換為 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM