I use SQL Server 2005. I have three columns in a table (ref, column1, column2). Columns 1 and 2 are float, ref is 1, column1 is 1000 and column2is 1000.
select *
from table
where ref = 1 and column1 = column2
returns 0 row(s)
I converted them to decimal and they are same.
They seem equal but query returns that they are not equal. How could it be possible?
edit:
Here is the screenshot. They are not same. What causes this and how can i fix it?
Float type is an approximation. The best way to use it in comparing is to first convert it to integer or to decimal:
CAST(revenue AS NUMERIC(10,2))
But I am getting one row to run the following query. Please check.
DECLARE #TABLE TABLE (REF INT,COLUMN1 FLOAT,COLUMN2 FLOAT)
INSERT INTO #TABLE
SELECT 1,1000,1000
SELECT * FROM #TABLE WHERE REF = 1 and COLUMN1 = COLUMN2
Thanks.
Related
I have a conundrum....
There is a table with one NVARCHAR(50) Float column that has many rows with many numbers of various decimal lengths:
'3304.063'
'3304.0625'
'39.53'
'39.2'
I need to write a query to find only numbers with decimal places >= 4
First the query I wrote was:
SELECT
Column
FROM Tablename
WHERE Column LIKE '%.[0-9][0-9]%'
The above code finds all numbers with decimal places >= 2:
'3304.063'
'3304.0625'
'39.53'
Perfect! Now, I just need to increase the [0-9] by 2...
SELECT
Column
FROM Tablename
WHERE Column LIKE '%.[0-9][0-9][0-9][0-9]%'
this returned nothing! What?
Does anyone have an explanation as to what went wrong as well and/or a possible solution? I'm kind of stumped and my hunch is that it is some sort of 'LIKE' limitation..
Any help would be appreciated!
Thanks.
After your edit, you stated you are using FLOAT which is an approximate value stored as 4 or 8 bytes, or 7 or 15 digits of precision. The documents explicitly state that not all values in the data type range can be represented exactly. It also states you can use the STR() function when converting it which you'll need to get your formatting right. Here is how:
declare #table table (columnName float)
insert into #table
values
('3304.063'),
('3304.0625'),
('39.53'),
('39.2')
--see the conversion
select * , str(columnName,20,4)
from #table
--now use it in a where clause.
--Return all values where the last digit isn't 0 from STR() the conversion
select *
from #table
where right(str(columnName,20,4),1) != 0
OLD ANSWER
Your LIKE statement would do it, and here is another way just to show they both work.
declare #table table (columnName varchar(64))
insert into #table
values
('3304.063'),
('3304.0625'),
('39.53'),
('39.2')
select *
from #table
where len(right(columnName,len(columnName) - charindex('.',columnName))) >= 4
select *
from #table
where columnName like '%.[0-9][0-9][0-9][0-9]%'
One thing that could be causing this is a space in the number somewhere... since you said the column type was VARCHAR this is a possibility, and could be avoided by storing the value as DECIMAL
declare #table table (columnName varchar(64))
insert into #table
values
('3304.063'),
('3304. 0625'), --notice the space here
('39.53'),
('39.2')
--this would return nothing
select *
from #table
where columnName like '%.[0-9][0-9][0-9][0-9]%'
How to find out if this is the case?
select *
from #table
where columnName like '% %'
Or, anything but numbers and decimals:
select *
from #table
where columnName like '%[^.0-9]%'
The following is working fine for me:
declare #tab table (val varchar(50))
insert into #tab
select '3304.063'
union select '3304.0625'
union select '39.53'
union select '39.2'
select * from #tab
where val like '%.[0-9][0-9][0-9][0-9]%'
Assuming your table only has numerical data, you can cast them to decimal and then compare:
SELECT COLUMN
FROM tablename
WHERE CAST(COLUMN AS DECIMAL(19,4)) <> CAST(COLUMN AS DECIMAL(19,3))
You'd want to test the performance of this against using the character data type solutions that others have already suggested.
You can use REVERSE:
declare #vals table ([Val] nvarchar(50))
insert into #vals values ('3304.063'), ('3304.0625'), ('39.53'), ('39.2')
select [Val]
from #Vals
where charindex('.',reverse([Val]))>4
(Beginner at sql)
I've been getting the error
'Error converting data type nvarchar to float.'
Which is because I was trying to round an nvarchar(10) column with both characters and integers, and obviously it can't round the characters. (I can't make two separate columns with different data types as they both need to be in this column)
I'm looking for a way to round the numbers in the nvarchar column whilst also returning the characters
I've being trying CAST/Converts nothing seems to work
I've also tried
CASE WHEN ISNUMERIC(Tbl1.Column1) = 1
THEN cast(Round(Tbl1.Column1, 0) AS float)
ELSE Tbl1.Column1 END AS 'Column1'
in the select statement
I cant figure out what else will solve this!
Sample Data in this column would be
8.1
2
9.0
9.6
A
-
5.3
D
E
5.1
-
I would go for try_convert() instead of isnumeric():
COALESCE(CONVERT(VARCHAR(255), TRY_CONVERT(DECIMAL(10, 0), Tbl1.Column1)),Tbl1.Column1) as Column1
A conversion problem arises with your approach because a case expression returns a single value. One of the branches is numeric, so the return type is numeric -- and the conversion in the else fails.
You can fix your version by converting the then clause to a string after converting to a float.
since you hold both types in this column, you need to cast your rounded value back to varchar
declare #Tbl1 table (Column1 varchar(10))
insert into #Tbl1 (Column1) values ('8.1'), ('2'), ('9.0'),
('9.6'), ('A'), ('5.3'),
('D'), ('E'), ('5.1'), ('-')
select case when TRY_CONVERT(float, Column1) IS NULL then Column1
else cast(cast(Round(Column1, 0) as float) as varchar(10))
end AS 'Column1'
from #Tbl1
outcome is
Column1
-------
8
2
9
10
A
5
D
E
5
-
In case you get the error TRY_CONVERTis not a build-in function then you have your database compatibility level is less that SQL 2012.
You can correct that using this command
ALTER DATABASE your_database SET COMPATIBILITY_LEVEL = 120;
Also note that after this statement the answer of Gordon is working now, and I agree that is a better answer then mine
I have a table with a column of varchar type. The column contains 568710 records of numeric (I mean the ISNUMERIC() returns 1) and 91 records of null values (i.e., the ISNUMERIC() returns 0). Now, I need to convert the column to FLOAT without losing the null records or replacing them with any other value. Is it possible in SQL?
When I use CONVERT(FLOAT, [Value]) conversion, I get the following error:
Msg 8114, Level 16, State 5, Line 48
Error converting data type varchar to float.
I read that the null can be converted to any type. So it should be possible.
You can use this
SELECT CONVERT(float, CASE WHEN ISNUMERIC(columnName) = 1 THEN columnName ELSE NULL END) FROM TableABC
Try :::
ALTER TABLE tablename
ADD NewFloatColumn FLOAT
UPDATE TableName
SET NewFloatColumn =
CASE WHEN ISNUMERIC(VarcharColumn) =1 THEN CAST (VarcharColumn AS float)
WHEN UPPER(VarcharColumn) = 'NULL' THEN null
END
Select (CASE WHEN ISNUMERIC(c) = 1
THEN (CASE WHEN c LIKE '%.%' THEN c ELSE c + '.00' END)
ELSE '0.00'
END)from table_name
I just spent some time scratching my head at the same problem. I was able to resolve this by converting first to int, then to float. Testing shows no data loss as my float column did not contain decimal, it simply had to match the dtype of another column for a later UNION operation.
This was completed on SQL Server 2016.
ALTER TABLE table1
ALTER COLUMN column1 int;
ALTER TABLE table1
ALTER COLUMN column1 float;
I have a varchar column that can either be a money or decimal data type. Sample values stored are 500 & .02 for each example.
How can I test to see if it's Money or a decimal and if it is a decimal add a leading 0 in front of it so the result will be 0.02?
Thanks in advance
Here is how you could convert all of the data to be consistently displayed as the Money datatype.
DECLARE #BadDesign TABLE (
BadDataTyping VARCHAR(100)
)
INSERT INTO #BadDesign (BadDataTyping) VALUES ('500')
INSERT INTO #BadDesign (BadDataTyping) VALUES ('.02')
SELECT * FROM #BadDesign
SELECT CONVERT(MONEY,BadDataTyping) FROM #BadDesign
UPDATE #BadDesign
SET BadDataTyping=CONVERT(MONEY,BadDataTyping)
SELECT * FROM #BadDesign
Maybe it will be helpful for you:
SELECT REPLACE(REPLACE('500 & .02','&',''),' ','')::DECIMAL(15,2); -- result: 500.02 (decimal)
Maybe this is what you're looking for? It takes all values with a leading "." and adds a "0". The search pattern in the 3rd row can be adjusted if you want to identify you're decimal values somehow differently.
SELECT
CASE TRUE
WHEN LEFT( col1, 1 ) = "." THEN CONCAT('0', col1 )
ELSE col1
END AS col1_formatted
FROM tab1
I have two table. First table(Table1) use to get the records and second table(Table2) used to insert first table record into it. But I am little bit confused after getting result.
In table 1 and table 2 column "Amount" have same data type i.e nvarchar(max)
Table1
Id Amount
1 Null
2 -89437.43
2 -533.43
3 22403.88
If I run this query
Insert into Table2(Amount)
Select Amount from Table1
Then get result like this, I don't know why values are automatically rounded off
Table2
Id Amount
1 Null
2 -89437.4
2 -533.43
3 22403.9
SQL Server will round float values when converting back and to from string types.
And then you have the fun bits of empty string being 0, as well other strange effects
SELECT CAST(CAST('' AS float) AS nvarchar(MAX))
SELECT CAST(CAST('0.E0' AS float) AS nvarchar(MAX))
Use decimal.
If you need to store "blank" (how does this differ from NULL?) use a separate bit column to allow that extra value
Here is good explanation about your question.
Eigher you explicitly give float or decimal or numeric(xx,x) (x means numeric value)
Then it will convert as the data, other wise it round off the last value.
Insert into Table2(Amount)
Select cast(Amount as numeric(18,2) --or , cast (Amount as float)
from Table1
Check this link:-
TSQL Round up decimal number
In my case I was doing the conversion to the correct data type but had decimal(18,0) for the column in the table. So make sure the decimal places are represented properly for the column decimal(18,2).
Perhaps it's your query tool that's truncating to 8 characters.
Check the actual fields lengths to see if the problem is really in the database:
SELECT LEN(Amount)
FROM Table2
WHERE Amount LIKE '%-89437.%'
Unreproducible. Running this script on SQL Server 2012:
DECLARE #T1 TABLE ([Amount] nvarchar(max) NULL);
DECLARE #T2 TABLE ([Amount] nvarchar(max) NULL);
INSERT INTO #T1 ([Amount])
VALUES (NULL),('-89437.43'),('-533.43'),('22403.88');
Insert into #T2(Amount)
Select Amount from #T1;
SELECT * FROM #T2;
Produces this result:
Amount
NULL
-89437.43
-533.43
22403.88
The problem you describe does not exist.
This will show you the problem:
DECLARE #T1 TABLE ([Amount123456789] money NULL);
DECLARE #T2 TABLE ([Amount123456789] nvarchar(max) NULL);
INSERT INTO #T1 ([Amount123456789])
VALUES (NULL),('-89437.43123'),('-533.43456'),('22403.88789'),(22403.88789);
Insert into #T2(Amount123456789)
Select Amount123456789 from #T1;
SELECT * FROM #T1;
SELECT * FROM #T2;