【问题标题】:SQL is rounding my decimal on castSQL 正在四舍五入我的小数点
【发布时间】:2024-01-05 07:15:01
【问题描述】:

我使用的是 SQL Server 2005。数据类型是 varchar。我正在尝试将数字转换为

1250000

1.25

在 SQL 查询中并删除尾随零。我尝试了很多事情都没有成功 - 遇到“修剪不是函数”等。

这是我目前所拥有的,在我尝试的每次迭代中。

select top 30 
    var1, var2, var3, var4, 
    CONVERT(DECIMAL(6,2), (var5 / 1000000)) as 'Number' 
from 
    databasetable 
where 
    var1 = x 

select top 30 
    var1, var2, var3, var4, 
    cast((var5 / 1000000) as decimal(6,2)) as 'Number' 
from 
    databasetable 
where 
    var1 = x 

以上两个查询都四舍五入到最接近的百万,即 1250000 变为 1.00,等等。任何想法都将不胜感激。将小数改为数字也无济于事。

【问题讨论】:

  • 想添加第一个查询字符串在 SQL Server 2000 中运行良好;由于最近的升级,我遇到了问题。
  • 您应该使用相关信息编辑您的问题,而不是发表评论。
  • 你可以试试 - cast(var5 as decimal(10,2))/ 1000000
  • Bad habits to kick : choosing the wrong data type - 你应该始终使用最合适的数据类型 - 毕竟这就是他们的目的!不要在varchar 列中存储数值
  • Yosi,这很接近。现在我得到 1.250000000 等等。

标签: c# sql sql-server decimal converter


【解决方案1】:

@marc_s 绝对正确 - stop storing numbers as strings!

也就是说,您是整数数学的受害者。试试:

SELECT CONVERT(DECIMAL(10,2), (var5 / 1000000.0)) 

由于您将数字存储为字符串,SQL Server 可能会在应用过滤器之前尝试使用非数字数据执行此计算,因此您可以说:

SELECT CONVERT(DECIMAL(10,2), (CASE WHEN ISNUMERIC(var5) = 1 THEN var5 END / 1000000.0))

[Note that this isn't perfect either.]

如果这不起作用,那么您有一些错误的数据。如果以下确实有效,但产生的小数位数过多:

select 
    var1, ...,
    CONVERT(DECIMAL(10,2), var5) / 1000000 as [Number] 

然后尝试用额外的转换包装它:

select 
    var1, ...,
    CONVERT(DECIMAL(10,2), CONVERT(DECIMAL(10,2), var5) / 1000000) as [Number]

说了这么多,为什么不能在表示层格式化这个数字呢?

另外,请不要将'single quotes' 用于列别名...this syntax is deprecated in some forms,它会错误地使您的列别名看起来像一个字符串(恕我直言)。使用[square brackets] 或避免使用关键字作为别名。

【讨论】:

  • 产生了 [Err] 22003 - [SQL Server]将 nvarchar 转换为数据类型数字的算术溢出错误。我知道不要将数字存储为字符串 - 我的双手被束缚了。不是我的数据库;我只是试图修复它的人。 :( 非常感谢所有的建议。
  • 更新答案,SQL Server 可能是在过滤之前应用计算,并试图划分垃圾数据。
  • 嗯。该修复具有相同的错误 - [Err] 22003 - [SQL Server]将 nvarchar 转换为数据类型 numeric 的算术溢出错误。
  • @user2697262 和 /1000000 有效吗?您能否将样本数据缩小到导致问题的值?
  • 亚伦,你是我的新英雄。 CONVERT(DECIMAL(10,2), CONVERT(DECIMAL(10,2), var5) / 1000000) 成功了。
【解决方案2】:

如果不知道您是确切的平台,我不能肯定地说,但我的猜测是将其截断为 int。在进行数学运算之前,我会尝试转换 var510000000。类似的东西

// NOTE, I have not tried this code
CONVERT(DECIMAL(6,2), (CONVERT(DECIMAL(6,2), var5) / CONVERT(DECIMAL(6,2), 1000000)))

【讨论】:

  • 这会产生 [Err] 22003 - [SQL Server] 将 int 转换为数据类型 numeric 的算术溢出错误。
【解决方案3】:
   select convert(decimal(5,2),convert(decimal(10,3),var5) / 1000000) where isnumeric(var5)=1

【讨论】:

  • 这个产生错误:[Err] 22003 - [SQL Server]将 nvarchar 转换为数据类型 numeric 的算术溢出错误。
【解决方案4】:
DECLARE @MyTable TABLE
(
    ColA VARCHAR(50) NOT NULL
);
INSERT INTO @MyTable (ColA) VALUES ('1250000');
INSERT INTO @MyTable (ColA) VALUES ('125');
INSERT INTO @MyTable (ColA) VALUES ('12');
INSERT INTO @MyTable (ColA) VALUES ('1');
INSERT INTO @MyTable (ColA) VALUES ('');
INSERT INTO @MyTable (ColA) VALUES ('e5');
INSERT INTO @MyTable (ColA) VALUES ('0x34abc');

SELECT  *, 
        w.ColB / 1000000.0 AS ColC,
        CONVERT(NUMERIC(4,2), w.ColB / 1000000.0) AS ColD, -- The result is rounded to 2 decimals; You should change default precision (4) and scale (2)
        STR(w.ColB / 1000000.0, 5, 2) AS ColE, -- The result is rounded to 2 decimals; You should change default lenght (5) and scale (2)       
        w.ColB * 1.0 / POWER(10, ColLength-1) AS ColF
FROM
(
    SELECT  *,
            CASE 
                -- It assumes that all values are INT[egers] without sign (+/-)
                WHEN PATINDEX('%[^0-9]%', RTRIM(LTRIM(v.ColA))) = 0 AND LEN(LTRIM(v.ColA)) BETWEEN 1 AND 11 THEN CONVERT(INT, v.ColA)
                ELSE NULL -- It returns NULL if the value cann't be converted to INT
            END AS ColB,
            LEN(LTRIM(v.ColA)) AS ColLength
    FROM    @MyTable v
) w

结果:

ColA    ColB    ColLength ColC        ColD ColE  ColF
------- ------- --------- ----------- ---- ----- --------------
1250000 1250000 7         1.250000000 1.25  1.25 1.250000000000
125     125     3         0.000125000 0.00  0.00 1.250000000000
12      12      2         0.000012000 0.00  0.00 1.200000000000
1       1       1         0.000001000 0.00  0.00 1.000000000000
        NULL    0         NULL        NULL NULL  NULL
e5      NULL    2         NULL        NULL NULL  NULL
0x34abc NULL    7         NULL        NULL NULL  NULL

【讨论】:

    最近更新 更多