I have a table with one float field:
CREATE TABLE IMPORTES (IMPORTE FLOAT)
Then I run these instructions:
INSERT INTO IMPORTES (IMPORTE) VALUES (15226.25)
INSERT INTO IMPORTES (IMPORTE) VALUES (9999.25)
INSERT INTO IMPORTES (IMPORTE) VALUES (5226.25)
When I execute SELECT CAST(IMPORTE AS NVARCHAR(40)), the biggest value gets rounded so that 15226.25 becomes 15226.3. Why is that? How can I make the Cast but still get the same value?
According to the documentation here for CAST and CONVERT, for float and real expressions, the style argument to CONVERT defaults to 0, which returns a maximum of 6 digits. Apparently CAST is actually calling CONVERT with this default value "under the hood", so to speak. The only way you are going to get consistent results is if you change the data type of IMPORTE to numeric(18,2), for instance, if you always know that you will only have 2 decimal places.
Related
One of my columns process_size holds a value 800089856 in bytes.
My SQL query says
select ((process_size*11/(1024*1024*1024))*100)/(4*3600) as Avg_wk_sum from instances where wk_id = 2
But instead of a float value it shows 0.
I even tried explicit cast
select ((process_size*11/(1024*1024*1024))*100)/(4*3600) :: float as Avg_wk_sum from instances where wk_id = 2
What am I doing wrong? How can I get the float value?
All values in your statement are integers, so the actual division/multiplication is carried out using integers - which yields 0. You then cast the result (0) to a float which doesn't change anything.
You should cast process_size to a float, then all subsequent operations are carried out using floats.
select ((process_size::float*11/(1024*1024*1024))*100)/(4*3600)
However if you care about precise results, you should stay away from approximate data types like float and use numeric instead.
DECLARE #TAX VARCHAR(30)=120.45
DECLARE #TaxRoundOf VARCHAR(30)
SET #TaxRoundOf=ROUND(#TAX,1)
SELECT #TaxRoundOf
This Gives Result (#TaxRoundOf=120.5)
DECLARE #TAX VARCHAR(30)=146.45
DECLARE #TaxRoundOf VARCHAR(30)
SET #TaxRoundOf=ROUND(#TAX,1)
SELECT #TaxRoundOf
This Gives Result (#TaxRoundOf=146.4)
But I need to return 146.50 . why this mismatch between two results?
any one can help plz?
Since you are using VARCHAR to store your numbers, SQL Server is having to do implicit conversion to float behind the scenes, which is having knock on effects on your calculations. You can reproduce this using the below query:
SELECT ROUND(CONVERT(FLOAT, 120.45),1), -- 120.5
ROUND(CONVERT(FLOAT, 146.45),1), -- 146.4
ROUND(CONVERT(DECIMAL(10, 2), 120.45),1), -- 120.50
ROUND(CONVERT(DECIMAL(10, 2), 146.45),1) -- 146.50
Since floating point numbers are not exact, 146.45 cannot be exactly represented as a float, and ends up being stored as a very slightly smaller number, so when this is passed to the round function, it is rounded down, instead of up.
The solution, as demonstrated by the 3rd and 4th columns in the above query, is to use a more precise data type.
You can use this:
SET #TaxRoundOf=ROUND(10 * CAST(#TAX AS FLOAT)) / 10
instead of:
SET #TaxRoundOf=ROUND(#TAX,1)
DEMO
PS as #GarethD already mentioned I wouldn't use #TAX as VARCHAR type.
You can also rely on numeric rounding instead of converting your string to a float, which can lose information.
Cast a string to numeric and then round:
select round(cast('146.45' as numeric(18,2)), 1)
-- 146.50
A decimal constant is already a decimal so there's no need to cast it:
select round(146.45, 1)
-- 146.50
I am inserting float numbers in Microsoft SQL and some of them appears as:
7E-05
5E-05
6E-05
The other float are inserted as expected.
For example this float 0.00007 is inserted as 7E-05 but this one 0.01500 as 0.015.
I was suspecting the size of float but after reducing it to x.yyyyy I still get this kind of float.
Anyone know what causing this issue?
If you want to store values like this, use DECIMAL instead of FLOAT in following: DECIMAL(18,5) It will allow your to store number with 5 digits after ,
Sample:
CREATE TABLE #test
(
ID DECIMAL(18,5)
)
INSERT INTO #Test VALUES (0.00007)
SELECT ID FROM #Test
DROP TABLE #Test
Result:
0.00007
As Jon Skeet said:
You're not actually trying to save 123.66, because you can't represent
123.66 exactly as a float or double. The database is saving the data more accurately than you're used to, that's all.
If you want to save decimal numbers accurately, use the decimal type.
You can read more at:
Link 1
Link 2
Link 3
Link 4
This is a simple example of what is not working for me:
CREATE TABLE Vertex(
PointID CHARACTER(15) PRIMARY KEY,
Height FLOAT(6,3)
);
After input like this:
INSERT INTO Vertex values("Tryout 1",555.22689562);
I expect the Height to be saved with the value: 555.227
However it is not the case for me, I keep finding the whole number being saved.
Could you point me to an alternate of how to define a column type and contain the format xxxxxx.xxx
Change float to decimal and it will work.
Height decimal(6,3)
Float is an approximate number data type. Using float may cause loss of precision, and using float data type for equality may not work all times.
Decimal data type is fixed precision data type. For using decimal data types, you will need to convert to the data type like convert(decimal(6,3), <number>).
In case of insert query, it is done implicitly though.
I am using LIKE to return matching numeric results against a float field. It seems that once there are more than 4 digits to the left of the decimal, values that match my search item on the right side of the decimal are not returned. Here's an example illustrating the situation:
CREATE TABLE number_like_test (
num [FLOAT] NULL
)
INSERT INTO number_like_test (num) VALUES (1234.56)
INSERT INTO number_like_test (num) VALUES (3457.68)
INSERT INTO number_like_test (num) VALUES (13457.68)
INSERT INTO number_like_test (num) VALUES (1234.76)
INSERT INTO number_like_test (num) VALUES (23456.78)
SELECT num FROM number_like_test
WHERE num LIKE '%68%'
That query does not return the record with the value of 12357.68, but it does return the record with the value of 3457.68. Also running the query with 78 instead of 68 does not return the 23456.78 record, but using 76 returns the 1234.76 record.
So to get to the question: why having a larger number causes these results to change? How can I change my query to get the expected results?
The like operator requires a string as a left-hand value. According to the documentation, a conversion from float to varchar can use several styles:
Value Output
0 (default) A maximum of 6 digits. Use in scientific notation, when appropriate.
1 Always 8 digits. Always use in scientific notation.
2 Always 16 digits. Always use in scientific notation.
The default style will work fine for the six digits in 3457.68, but not for the seven digits in 13457.68. To use 16 digits instead of 6, you could use convert and specify style 2. Style 2 represents a number like 3.457680000000000e+003. But that wouldn't work for the first two digits, and you get an unexpected +003 exponent for free.
The best approach is probably a conversion from float to decimal. That conversion allows you to specify the scale and precision. Using scale 20 and precision 10, the float is represented as 3457.6800000000:
where convert(decimal(20,10), num) like '%68%'
When you are comparing number with LIKE it is implicitly converted to string and then matched
The problem here is that float number is not precise and when it is converted you can get
13457.679999999999999 instead of 13457.68
So to avid this explicitly format number in appropriate format(not sure how to do this in sql server, but it will be something like)
SELECT num FROM number_like_test
WHERE Format("0.##",num) LIKE '%68%'
The conversion to string is rounding your values. Both CONVERT and CAST have the same behavior.
SELECT cast(num as nvarchar(50)) as s
FROM number_like_test
Or
SELECT convert(nvarchar(50), num) as s
FROM number_like_test
provide the results:
1234.56
3457.68
13457.7
1234.76
23456.8
You'll have to use the STR function and correct format parameters to try to get your results. For example,
SELECT STR(num, 10, 2) as s
FROM number_like_test
gives:
1234.56
3457.68
13457.68
1234.76
23456.78
Pretty well solved already, but you only need to CAST once, not twice like the other answer suggests, LIKE takes care of the string conversion:
SELECT *
FROM number_like_test
WHERE CAST(num AS DECIMAL(12,6)) LIKE '%68%'
And here's a SQL Fiddle showing the rounding behavior: SQL Fiddle
It's probably because a FLOAT data type represents a floating point number which is an approximation of the number and should not be relied on for exact comparisons.
If you need to do a search that includes the float value you would need to either store it in a decimal data type (which will hold the exact number) or convert it to a varchar using something like the STR() function