简体   繁体   English

SQL-varchar列中的小数

[英]SQL - Decimals in varchar columns

Why is this query pulling 99.73 when I have specified cast(measure_rate as decimal)= 100 ? 当我指定cast(measure_rate as decimal)= 100时,为什么此查询会拉99.73

;WITH cte AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY zip_code ORDER BY cast(measure_rate as decimal) DESC) AS rn
   FROM AmbulatoryMeasures
   where measure_rate != 'n/a'
)
SELECT * 
FROM cte
WHERE rn = 1
and cast(measure_rate as decimal) = 100

The result of the measure_rate column - measure_rate列的结果-

100
99.73
100
100

The data type of the measure_rate column is a varchar(50). measure_rate列的数据类型为varchar(50)。

I would not expect 99.73 value in the result set because of the where clause. 由于where子句,我不希望结果集中有99.73值。

The default number of decimals is 0 . 默认的小数位数为0 If you specify the decimal with precision and scale you get the correct result you are after: 如果您以精度和小数位数指定小数,则会得到正确的结果:

SELECT CAST('99.73' AS DECIMAL(18,2))

If you cast 99.73 to DECIMAL you get 100 so the result is expected, to consider the decimal part do something like this for 2 decimals precision 如果将99.73强制转换为DECIMAL,则得到100,因此可以得到预期结果,请考虑将小数部分作为2小数精度进行如下操作

 CAST(measure_rate AS DECIMAL(38, 2))

(38 for precision is just an example, select a number that suits your data better) (38精度只是一个示例,请选择一个更适合您数据的数字)

You don't have a scale or precision for your decimal so the default is used. 您的decimal或精度,因此使用默认值。 This likely means that the scale is set to 0 so '99.73' is cast to 100 due to rounding. 这可能意味着小数'99.73'设置为0,因此由于舍入, '99.73'100

If you change your data type of your column in your table from a varchar to decimal with an appropriate scale and precision this won't happen. 如果将表中列的数据类型从varchar更改为具有适当比例和精度的decimal ,则不会发生这种情况。 This is just one reason why choosing the wrong data type is a bad decision. 这只是选择错误数据类型是一个错误决定的原因之一。

You need to define precision of decimal number of digits and number oof decimal placies you can use 您需要定义十进制数字的精度和可以使用的十进制数的位数

;WITH cte AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY zip_code ORDER BY cast(measure_rate as decimal) DESC) AS rn
   FROM AmbulatoryMeasures
   where measure_rate != 'n/a'
)
SELECT * 
FROM cte
WHERE rn = 1
and cast(measure_rate as decimal(16,2)) = 100

You should specify precision, while casting to DECIMAL. 在转换为DECIMAL时,应指定精度。 Consider following two snippets. 考虑以下两个片段。

    --Your situation - no precision 
        DECLARE @test AS TABLE(MYVALUE VARCHAR(50));
        INSERT INTO @test
               SELECT '99.73';
        SELECT myvalue, 
               CAST(myvalue AS DECIMAL)
        FROM @test
        WHERE CAST(myvalue AS DECIMAL) = 100;

--Casting with precision         
        DECLARE @test2 AS TABLE(MYVALUE VARCHAR(50));
        INSERT INTO @test2
               SELECT '99.73';
        SELECT myvalue, 
               CAST(myvalue AS DECIMAL(10,2))
        FROM @test2

The result is shown in the picture below. 结果如下图所示。 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM