简体   繁体   中英

SQL - Decimals in varchar columns

Why is this query pulling 99.73 when I have specified cast(measure_rate as decimal)= 100 ?

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

100
99.73
100
100

The data type of the measure_rate column is a varchar(50).

I would not expect 99.73 value in the result set because of the where clause.

The default number of decimals is 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

 CAST(measure_rate AS DECIMAL(38, 2))

(38 for precision is just an example, select a number that suits your data better)

You don't have a scale or precision for your decimal so the default is used. This likely means that the scale is set to 0 so '99.73' is cast to 100 due to rounding.

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. 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. 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. 在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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