LEFT returns different results for the same values - sql

Can some one explain me why the results of LEFT are different? For:
Declare #f as float
set #f = 40456510.
select LEFT(cast(#f as float), LEN(4045.)), LEFT(404565., LEN(4045.))
I got:
|
------------
4.04 | 4045
Is there a default cast which causes this? Fiddle SQL

When you call LEFT(...) on the FLOAT value you are converting it to a string representation of the number as it's a string function. If you convert the value to a varchar for example, you'll see what the output is:
SELECT CAST(CAST(#f as float) AS VARCHAR(100))
You get: '4.04565e+007'
So the first 4 characters of that are: '4.04'

The first one is taking the left 4 characters of the exponential representation. Why I don't know.
You are applying a string function [Left()] to a float variable.

Related

Why rand() in format function returns null?

I want to generate a 6 digit number in SQL Server, which first digit is allowed to be zero.
For generating a random 6 digit number I use this code:
round(rand()*power(10,6),0)
For making sure that it is a 6 character number I use as this example:
format(12345,'D6')
Which returns:
012345
But when I use below phrase it returns NULL
select format(round(rand()*power(10,6),0),'D6')
I was searching to find the cause, but I just understand that even format(rand()*power(10,6),'D6') returns null, while format(round(power(10,3),0),'D6') and select format(power(10,3),'D6') returns the answer.
It shows that the problem is neither about power() nor round(). The rand() function is the cause.
I use this code to solve my problem:
declare #num int = round(rand()*power(10,6),0)
select format(#num,'D6')
But I just want to know why rand() in format() returns null, I couldn't find the cause.
If you have any idea, I'll appreciate it.
Thanks.
The function rand()*power(10,6) returns a float.
When you put it into a variable type int you force the conversion to int.
We can do the same thing with cast(.. as int) as in
select format(cast(rand()*power(10,6)as int),'D6') which works correctly. (As the value is already a whole number there is no need to use round())
If we use a variable type float we get a null value:
declare #num float = round(rand()*power(10,6),0)
select format(#num,'D6')
| (No column name) |
| :--------------- |
| null |
The problem therefore occurs when we use format() with a float as argument.

How to multiply string value to longint in SQL

I have the below data which I want to multiply together, column A times column B to get column C.
A has datatype string and B has datatype long.
A B
16% 894
15% 200
I have tried this expression in query cast(A as int)*B but it is giving me an error.
You can try below way -
select cast(left(A, patindex('%[^0-9]%', A+'.') - 1) as int)*B
from tablename
You need to remove the '%' symbol before attempting your cast. And assuming you are actually wanting to calculate the percentage, then you also need to divide by 100.00.
cast(replace(A,'%','') as int)/100.00*B
Note: You need to use 100.00 rather than 100 to force decimal arithmetic instead of integer. Or you could cast as decimal(9,2) instead of int - either way ensures you get an accurate result.
You may well want to reduce the number of decimal points returned, in which case cast it back to your desired datatype e.g.
cast(cast(replace(A,'%','') as int)/100.00*# as decimal(9,2))
Note: decimal(9,2) is just an example - you would use whatever precision and scale you need.
The syntax of the cast in SQL Server is CAST(expression AS TYPE);
As you cannot convert '%' to an integer so you have to replace that with an empty character
as below:
SELECT cast(replace(A,'%','') AS int);
Finally you can write as below:
SELECT (cast(replace(A,'%','') AS int)/100.00)*B as C;

Error converting data type varchar to float isnumeric = 1

When I run the script:
select
cast(s as float)
from
t
where
ISNUMERIC(s) = 1
it stops with the error:
Error converting data type varchar to float.
Why does it happen? I'm trying to convert to float only numerics. How do I found out which row causes the error?
The isnumeric function thinks just about everything is a number. Use "try_convert" instead. if the value can't convert to your destination datatype, it returns null.
select convert(float, '1,0,1')
where try_convert(float, '1,0,1') is not null
If you are on an older version of SQL, I would write my own function.
I usually face with this when the value in a column you are trying to convert to float contains a comma (,) as thousand separator:
SELECT ISNUMERIC('140,523.86')
The Result is 1, but unable to cast it as a float.
By replacing it works fine for me:
SELECT
CAST( replace(s,',','') AS float ) AS Result
FROM t
WHERE ISNUMERIC(replace(s,',','')) = 1
ISNUMERIC() function will return 1 for values like 123e3 because these values are Interpreted as numeric values. Because sql server sees this as 123 , 3 to the powers of 10 which is really a numeric value.
You should try something like....
Select *
From tableName
WHERE Col NOT LIKE '%[^0-9]%'
This will return any row where there is a non-numeric character, even values with a ..

SQL server 'like' against a float field produces inconsistent results

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

how to convert different datatypes to int in sql

I have a nvarchar(200) column in a table that contains a mix of integers (as strings) and non-integer strings and symbols also. E.g. Some sample data :-
Excuse me for my typing in my initial post I mentioned varchar(200) but in fact it is 'nvarchar(200)'
02
0
.../
125
00125
/2009
1000
0002589
000.00125
Marathi numbers like & letters
how can I order this Column?
You can use CAST to convert a varchar to an INT given that varchar is holding a proper number.
SELECT CAST(varCharCol as Int)
E.g.
col1 as Varchar(10)
col1 = '100' converting to INT will be successufl
but if col1 = '100 xyz' will be unsucessful in the process.
Looking at your string you may have to use number of LTRIM, REPLACE to get hold of the digits or using a regex to get comma separated numbers. That too it's not very clear how your original string looks like.
References.
Many DBMS have CAST() functions where you can convert one datatype to another.
For MySQL have a look at this site
You can Use CAST and Convert to convert string type value to int type. but be sure the value should numeric.
select convert(int,'123')
select CAST('123' as int)
You can use this query
SELECT CASE
WHEN ISNUMERIC(colName)=1 THEN ROUND(colName, 0)
ELSE 0 END AS [colName]
FROM tblName