Decimal values in SQL for dividing results - sql-server

In SQL, I have col1 and col2. Both are integers.
I want to do like:
select col1/col2 from tbl1
I get the result 1 where col1=3 and col2=2
The result I want is 1.1
I put round(col1/col2,2). The result is still 1.
I put decimal(col1/col2,2). The decimal is not built in function.
How can I do exactly to get 1.1?

Just another approach:
SELECT col1 * 1.0 / col2 FROM tbl1
Multiplying by 1.0 turns an integer into a float numeric(13,1) and so works like a typecast, but most probably it is slower than that.
A slightly shorter variation suggested by Aleksandr Fedorenko in a comment:
SELECT col1 * 1. / col2 FROM tbl1
The effect would be basically the same. The only difference is that the multiplication result in this case would be numeric(12,0).
Principal advantage: less wordy than other approaches.

You will need to cast or convert the values to decimal before division. Take a look at this
http://msdn.microsoft.com/en-us/library/aa226054.aspx
For example
DECLARE #num1 int = 3 DECLARE #num2 int = 2
SELECT #num1/#num2
SELECT #num1/CONVERT(decimal(4,2), #num2)
The first SELECT will result in what you're seeing while the second SELECT will have the correct answer 1.500000

SELECT CAST (col1 as float) / col2 FROM tbl1
One cast should work. ("Less is more.")
From Books Online:
Returns the data type of the argument with the higher precedence. For more information about data type precedence, see Data Type Precedence (Transact-SQL).
If an integer dividend is divided by an integer divisor, the result is an integer that has any fractional part of the result truncated

CAST( ROUND(columnA *1.00 / columnB, 2) AS FLOAT)

There may be other ways to get your desired result.
Declare #a int
Declare #b int
SET #a = 3
SET #b=2
SELECT cast((cast(#a as float)/ cast(#b as float)) as float)

just convert denominator to decimal before division e.g
select col1 / CONVERT(decimal(4,2), col2) from tbl1

Related

Cast everything for 2 decimal points?

I want to divide two integers: 8/15 and return "53.33".
I've tried every single combination, and I've found that this is the only way I can return the desired value:
select cast(100*cast(8/cast(15 as decimal(10,4)) as decimal(18,4)) as decimal(18,2))
Is there a shorter way?
Thanks.
You are doing interger division. Use float, and multiply by 100.
select 8/15.00 * 100
Or, for your precision, just do the cast once
select cast(8/15.00 * 100 as decimal (10,2))
If these are integers in a table then multiple by 1.0 and cast once
DEMO
declare #table table (int_one int, int_two int)
insert into #table
values
(8,15)
select
cast(((int_one * 1.0) / int_two) * 100 as decimal(10,2))
from #table
try this:
select (cast (8 as money)/cast(15 as money) * 100)

MS SQL change Cast count VarChar to %

In the last line of the code I have listed below, The current result is blank because the result is less than 1. I need the results to display as a percentage but I'm not sure how. Any suggestions are greatly appreciated?
SELECT
'1,*'+char(13)+char(10)
+'80,1006058'+char(13)+char(10)
+'100,10'+char(13)+char(10)
+'2405,'+cast(count(distinct adt.PAT_ENC_CSN_ID) / 420 as varchar(18))+char(13)+char(10) --Census events --as varchar(10)
The issue is that your count(distinct adt.PAT_ENC_CSN_ID) returns an integer value and then you divide by 420. Another integer.
If you cast the count distinct as a decimal or float, this should solve your issue. CAST(COUNT(DISTINCT adt.PAT_ENC_CSN_ID) AS FLOAT).
SELECT
'1,*'+char(13)+char(10)
+'80,1006058'+char(13)+char(10)
+'100,10'+char(13)+char(10)
+'2405,'+cast( cast(count(distinct adt.PAT_ENC_CSN_ID) AS FLOAT) / cast(420 AS FLOAT) as varchar(18))+char(13)+char(10) --Census events --as varchar(10)
You should cast() your numbers as float otherwise they are considered as integers and you don't have decimals in your division because the result is also considered integer
Just replace this part
cast(count(distinct adt.PAT_ENC_CSN_ID) / 420 as varchar(18))
with
cast(count(distinct adt.PAT_ENC_CSN_ID) / 420.00 as varchar(18))
Note that all we did was turn 420 to 420.00 to suggest SQL to retain decimal part and not treat the result as integer.
As count return integer values and integer/integer is an integer but integer/decimal is decimal

How do you write a SQL query to find all the rows that has a float currency value like $15.34 in a nvarchar field

How do you write a SQL query to find only the rows that has a float currency value like $15.34 and NOT round currency value like 15 in a nvarchar field.
Assuming you have a mix of numeric and non-numeric, this should work to return all decimal values that are not whole dollar amounts:
Select * from tablename
where colname like '%.%' --Has a decimal (as in original query)
and colname not like '%.00' --Does not end with 00
It is as simple as
Select * from tablename where columnname = '15.34'
I would strip the $ out, and check if it evaluates to a numeric or not, and use a modulo to be sure a remainder remains when divided by 1.
DECLARE #TEST TABLE (columnname NVARCHAR(15))
INSERT INTO #TEST
SELECT '$15.34' UNION
SELECT 'ZERO' UNION
SELECT '$123.00'
SELECT *, CONVERT(MONEY,REPLACE(columnname,'$',''))
FROM #TEST
WHERE ISNUMERIC(REPLACE(columnname,'$',''))=1
AND CONVERT(MONEY,REPLACE(columnname,'$','')) % 1 != 0
You can use like
Select * from Yourtablename where Yourcolumnname like '$15.%'
Two things:
First, you want to find the rows having the $ in them.
WHERE LOCATE('$',columname) <> 0
Second, you want to find the rows where the rest of the value in the column is a floating point number.
AND CONVERT(REPLACE(columnname,'$',''),DECIMAL(10,2)) <> 0
That CONVERT() <>0 pattern works because MySQL silently returns zero when you try to convert a nonnumeric value to a number.

How to add or concatenate money type and string on query mssql

I have a situation like this
I got a column with 'money' type, 2 decimal . Example data:(65.00)
I need to add 12 zero / 000000000000 to it so that the output would be like this:
(65.00 convert to 6500) + (000000000000) = 000000006500
Output: 000000006500
How can I achieve this?. Thank you for your help and suggestion
You can do this with a couple of casts, multiplying by 100, and using REPLICATE('0') to pad with the requisite number of zeroes).
I'm assuming you DO want up to 2 x trailing decimals, but no more.
DECLARE #value MONEY;
SET #value = 65.123;
DECLARE #intValue BIGINT;
SET #intValue = CAST(#value * 100.0 AS BIGINT);
SELECT REPLICATE('0',12-LEN(#intValue)) + CAST(#intValue AS NVARCHAR(20));
Returns 000000006512
If you need to do this on a set, a CTE can be used for the intermediate step, e.g.
WITH cte AS
(
SELECT CAST(MoneyField * 100.0 AS BIGINT) AS intValue
FROM SomeTable
)
SELECT
REPLICATE('0',12-LEN(cte.intValue)) + CAST(cte.intValue AS NVARCHAR(20))
FROM cte;
Fiddle here
It is Possible .But output Column should be in the type of varchar(15) .If you want to do further operation of your output you have to convert that into int or whatever
SELECT CONCAT(REPEAT('0',12-LENGTH(65.00)),(65.00*100));

TSQL to identify long Float values

I'm dealing with a legacy system where I need to identify some bad records based on a column with a data type of Float.
Good records have a value of...
1
2
1.01
2.01
Bad records are anything such as..
1.009999999999999
2.003423785643000
3.009999990463260
I've tried a number of select statements where I Convert to Decimal and cast to a varchar and use the LEN() function but this don't seem to work as the good records that are 1.01 become 1.0100000000000000
--Edit
I'm a little closer now as I have discovered I can do (Weight * 100) and all of the good records become whole number values such as 101,201,265,301,500, etc...
and bad ones such as 2.00999999046326 become 200.999999046326
This works on my SQL Server 2005 DB:
select len(cast(cast(1.01 as float) as varchar))
Result:
4
In fact, it even lets me skip the explicit varchar cast if I want to:
select len(cast(1.011 as float))
Result:
5
Update: First of all, I still needed the cast to varchar. Thinking otherwise was wrong. That said, I had this all working using strings and was about to post how. Then you I your update on mulitpling by 100 and realized that was the way to go. So here's my code for testing both ways:
declare #test table ( c float)
insert into #test
select * from
( select 14.0100002288818 as c union
select 1.01 union
select 2.00999999046326 union
select 14.01
) t
select c,
case when c = cast(cast(c as varchar) as float) AND LEN(cast(c as varchar))<=5 then 1 else 0 end,
case when c * 100 = floor(c * 100) then 1 else 0 end
from #test
something like this, maybe? (adjust the precision/scale in the where clause, of course)
select val from mytable WHERE CONVERT(decimal(5,2), val) <> val
Have you thought about using CLR integration and using .net to handle the validation
see this link Basics of Using a .NET Assembly in MS SQL - User Functions
basically you use .net methods as a user defined function to do the validation; .NET is better at working with numbers.
You could do something like this:
SELECT *
FROM YourTable
WHERE CAST(YourFloatField AS DECIMAL(15,2)) <> YourFloatField
I'm assuming that anything "bad" has more than 2 decimal places given.
This really will become a pain in the neck because floats are an imprecise datatype and you will get implicit conversions when casting.
it also depends where you run something like the following
select convert(float,1.33)
in query analyzer the output is 1.3300000000000001
in SSMS the output is 1.33
when you convert to decimal you need to specify scale and precision
so if you do
select convert(decimal(10,6),convert(float,1.33))
you get this 1.330000 because you specified a scale of 6
you could do something like this where after converting to decimal you drop the trailing 0s
select replace(rtrim(replace(convert(varchar(30),
(convert(decimal(10,6),convert(float,1.33)))),'0',' ')),' ','0')
for a value of 3.00999999046326 you need a scale of at least 14
select replace(rtrim(replace(convert(varchar(30),
(convert(decimal(30,14),convert(float,3.00999999046326)))),'0',' ')),' ','0')
Run this:
DECLARE #d FLOAT;
SET #d = 1.23;
SELECT ABS(CAST(#d AS DECIMAL(10,2)) - CAST(#d AS DECIMAL(15,8)));
SET #d = 1.230000098;
SELECT ABS(CAST(#d AS DECIMAL(10,2)) - CAST(#d AS DECIMAL(15,8)));
Use some threshold such as:
ABS(CAST(#d AS DECIMAL(10,2)) - CAST(#d AS DECIMAL(15,8)))<0.00001

Resources