How to limit decimal values based on condition in SQL Server - sql-server

I have an amount field which is decimal(13,5) in SQl Server.
So it takes values like 22.23456 (5 values after decimals)
Now i want to limit the decimal places based on condition like below:
for 22.23456, result should be 22.24
for 22.20001, result should be 22.21
for 22.20000, result should be 22.20
for 22.00000, result should be 22.00
So if there is any number other than 0 after 2nd decimal place(in 1st ex:4),just increase the value 2nd decimal value by 1.(22.2345 to 22.24)
Is there any function or do we need to use length type functions to achieve this?
Please help.
Thanks in advance.

Since you want the highest value in the hundredths position using standard rounding will not work. You can however use a little math and CEILING to accomplish.
with MyValues(SomeValue) as
(
select 22.23456 union all
select 22.20001 union all
select 22.20000 union all
select 22.00000
)
select cast(ceiling(SomeValue * 100) / 100. as numeric(9,2)) as MyResult
from MyValues
https://msdn.microsoft.com/en-us/library/ms189818.aspx

Related

Way to show items where more than 5 decimal places occur?

I am trying to filter out some query results to where it only shows items with 6 decimal places. I don't need it to round up or add 0's to the answer, just filter out anything that is 5 decimal places or below. My current query looks like this: (ex. if item is 199.54215 i dont want to see it but if it is 145.253146 i need it returned)
select
TRA_CODPLANTA,
TRA_WO,
TRA_IMASTER,
tra_codtipotransaccion,
tra_Correlativo,
TRA_INGRESOFECHA,
abs(tra_cantidadparcial) as QTY
from mw_tra_transaccion
where FLOOR (Tra_cantidadparcial*100000) !=tra_cantidadparcial*100000
and substring(tra_imaster,1,2) not in ('CP','SG','PI','MR')
and TRA_CODPLANTA not in ('4Q' , '5C' , '5V' , '8H' , '7W' , 'BD', 'DP')
AND tra_INGRESOFECHA > #from_date
and abs(tra_cantidadparcial) > 0.00000
Any assistance would be greatly appreciated!
Here is an example with ROUND, which seems to be the ideal function to use, since it remains in the realms of numbers. If you have at most 5 decimal places, then rounding to 5 decimal places will leave the value unchanged.
create table #test (Tra_cantidadparcial decimal(20,10));
INSERT #test (Tra_cantidadparcial) VALUES (1),(99999.999999), (1.000001), (45.000001), (45.00001);
SELECT * FROM #test WHERE ROUND(Tra_cantidadparcial,5) != Tra_cantidadparcial;
drop table #test
If your database values are VARCHAR and exist in the DB like so:
100.123456
100.1
100.100
You can achieve this using a wildcard LIKE statement example
WHERE YOUR_COLUMN_NAME LIKE '%.[0-9][0-9][0-9][0-9][0-9][0-9]%'
This will being anything containing a decimal place followed by AT LEAST 6 numeric values
Here is an example using a conversion to varchar and using the LEN - the CHARINDEX of the decimal point, I'm not saying this is the best way, but you did ask for an example in syntax, so here you go:
--Temp Decimal value holding up to 10 decimal places and 10 whole number places
DECLARE #temp DECIMAL(20, 10) = 123.4565432135
--LEN returns an integer number of characters in the converted varchar
--CHARINDEX returns the integer location of the decimal where it is found in the varchar
--IF the number of characters left after subtracting the index of the decimal from the length of the varchar is greater than 5,
--you have more than 6 decimal places
IF LEN(CAST(#temp AS varchar(20))) - CHARINDEX('.', CAST(#temp AS varchar(20)), 0) > 5
SELECT 1
ELSE
SELECT 0
Here is a shorthand way.
WHERE (LEN(CONVERT(DOUBLE PRECISION, FieldName % 1)) - 2) >=5
One way would be to convert / cast that column to a lower precision. Doing this would cause automatic rounding, but that would show you if it is 6 decimals or not based on the last digit. If the last digit of the converted value is 0, then it's false, otherwise it's true.
declare #table table (v decimal(11,10))
insert into #table
values
(1.123456789),
(1.123456),
(1.123),
(1.123405678)
select
v
,cast(v as decimal(11,5)) --here, we are changing the value to have a precision of 5. Notice the rounding.
,right(cast(v as decimal(11,5)),1) --this is taking the last digit. If it's 0, we don't want it
from #table
Thus, your where clause would simply be.
where right(cast(tra_cantidadparcial as decimal(11,5)),1) > 0

Convert Numeric value like 177200 to 1772.00 in T-SQL statement

In SQL Server, I have a query that returns a value of 177200. I need this value represented as 1772.00 as the last 2 digits are past the decimal. The query below is adding .00 to the end of the full value. I have no experience in this type of SQL statement. Any help would be appreciated.
SELECT
STR(SUM(ActualPrice), 10, 2) AS Total, Department
FROM
#DepartmentSalesData
GROUP BY
Department
The data type you're looking for is called numeric
SELECT CAST(SUM(ActualPrice) / 100.0 AS numeric(18, 2)) AS Total, ...
FROM ...
You're passing in a precision (18 in my example) and a scale 2 in my example, as requested by you.

SQL Server: Calculate length before decimal places

I want to calculate the length of a values in a numeric column. The values are randomly as
255.0125 , 28847.0125 etc
I need the length of values before the decimal places only. So far the first value it should be 3, for second value it should be 5.
What SQL function can be helpful here.
I suggest using FLOOR function, add ABS as well if numbers can be negative:
SELECT LEN(FLOOR(9.99999))
SELECT LEN(FLOOR(ABS(-9.99999)))
This will fail
SELECT LEN(cast(-9.99999 as int))--Result 2
SELECT LEN(FLOOR(-9.99999))--Result 3
Try:
select len(cast(999999999.99999 as int))
select len(cast(28847.0125 as int))
Or
select len(cast('28847.0125' as decimal))
Or
select len(round('28847.0125', 0, 1))
Or
EDIT 2 suggestion by deepanshu-kalra
:
SELECT LEN(FLOOR(9.99999))
Use ROUND() function, which will convert decimal to int, then use LEN()
query will be
select LEN(ROUND('255.0125', 0))
ROUND() function systax :
ROUND(value,decimalPlace)

How to get a float result by dividing two integer values using T-SQL?

Using T-SQL and Microsoft SQL Server I would like to specify the number of decimal digits when I do a division between 2 integer numbers like:
select 1/3
That currently returns 0. I would like it to return 0,33.
Something like:
select round(1/3, -2)
But that doesn't work. How can I achieve the desired result?
The suggestions from stb and xiowl are fine if you're looking for a constant. If you need to use existing fields or parameters which are integers, you can cast them to be floats first:
SELECT CAST(1 AS float) / CAST(3 AS float)
or
SELECT CAST(MyIntField1 AS float) / CAST(MyIntField2 AS float)
Because SQL Server performs integer division. Try this:
select 1 * 1.0 / 3
This is helpful when you pass integers as params.
select x * 1.0 / y
It's not necessary to cast both of them. Result datatype for a division is always the one with the higher data type precedence. Thus the solution must be:
SELECT CAST(1 AS float) / 3
or
SELECT 1 / CAST(3 AS float)
use
select 1/3.0
This will do the job.
I understand that CASTing to FLOAT is not allowed in MySQL and will raise an error when you attempt to CAST(1 AS float) as stated at MySQL dev.
The workaround to this is a simple one. Just do
(1 + 0.0)
Then use ROUND to achieve a specific number of decimal places like
ROUND((1+0.0)/(2+0.0), 3)
The above SQL divides 1 by 2 and returns a float to 3 decimal places, as in it would be 0.500.
One can CAST to the following types: binary, char, date, datetime, decimal, json, nchar, signed, time, and unsigned.
Looks like this trick works in SQL Server and is shorter (based in previous answers)
SELECT 1.0*MyInt1/MyInt2
Or:
SELECT (1.0*MyInt1)/MyInt2
Use this
select cast((1*1.00)/3 AS DECIMAL(16,2)) as Result
Here in this sql first convert to float or multiply by 1.00 .Which output will be a float number.Here i consider 2 decimal places. You can choose what you need.
If you came here (just like me) to find the solution for integer value, here is the answer:
CAST(9/2 AS UNSIGNED)
returns 5
I was surprised to see select 0.7/0.9 returning 0.8 in Teradata given they're already as floats/decimal numbers! I had to do cast(0.7 as float) to get the output that I was after.
When using literals, the best way is to "tell" SQL
which type you mean.
if you want a decimal result, add decimal point ".0" to your numbers:
SELECT 1.0 / 3.0
Result
0.333333
if you want a float (real) result, add "e0" to your numbers:
SELECT 1e0 / 3e0
Result
0.333333333333333

Only display the values to the right of a Decimal Number

I use SQL Server 2005 and need to test whether values in a column that's metadata has been specified as DECIMAL(18.3) actually contains data that has values to the right of the Decimal point, and if so, what these values are.
I've read a few articles that only discuss how to drop off the decimal places or how to round the values, but not how to ONLY display what is stored to the right of the decimal point.
Your help would be greatly appreciated.
Kind Regards,
Ignacio.
Try:
SELECT a - FLOOR(a)
FROM ...
SELECT decimalnumber - FLOOR(decimalnumber) AS decimalpart
FROM mytable
WHERE decimalnumber - FLOOR(decimalnumber) > 0
This may not always work the way you expect it to. The problem occurs when you have negative numbers. You can think of FLOOR as a type of rounding, where it always rounds down to the next whole number. Floor(3.14) = 3, and Floor(-3.14) = -4.
To get the value of a number after the decimal point, you can use the ParseName function, which will work for positive and negative numbers.
Select ParseName(-3.9876, 1)
Select ParseName(-3.1234, 1)
Select ParseName(3.9876, 1)
Select ParseName(3.1234, 1)

Resources