1

我使用的是 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,等等。任何想法都将不胜感激。将十进制更改为数字也无济于事。

4

4 回答 4

4

@marc_s 是绝对正确的——停止将数字存储为字符串!

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

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

[请注意,这也不完美。]

如果这不起作用,那么你有一些坏数据。如果以下确实有效但产生了太多小数位:

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'用于列别名...这种语法在某些形式中已被弃用,并且它错误地使您的列别名看起来像一个字符串(恕我直言)。使用[square brackets]或避免使用关键字作为别名。

于 2013-09-03T20:47:53.453 回答
1

如果不知道您是确切的平台,我不能肯定地说,但我的猜测是将其截断为 int。我会在做数学之前var5尝试转换。10000000就像是

// NOTE, I have not tried this code
CONVERT(DECIMAL(6,2), (CONVERT(DECIMAL(6,2), var5) / CONVERT(DECIMAL(6,2), 1000000)))
于 2013-09-03T20:42:21.083 回答
0
   select convert(decimal(5,2),convert(decimal(10,3),var5) / 1000000) where isnumeric(var5)=1
于 2013-09-03T20:44:15.660 回答
0
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
于 2013-09-03T21:11:28.613 回答