Converting a monetary value like 1.223.01 to decimal - sql-server

I have a monetary value like 1.223.01 but it is stored as a varchar so it is really like '1.223.01'.
I need this to be converted to decimal so I can do some calculations on it.
What I have tried is
SELECT Convert(decimal(18,2), '1.223.01') AS test
But I get a conversion error.
How can I convert this?

You've not specified what the output should be, so it's either 1223.01 or 122301.00 that you require.
So using some basic string manipulation you can get both of those values:
DECLARE #val AS VARCHAR(20) = '1.223.01'
-- remove all decimal points
SET #val = REPLACE(#val, '.', '')
-- convert value without decimals to get 122301.00
SELECT CONVERT(decimal(18,2), #val) AS TestValue
-- add a decimal point before the last 2 digits to get 1223.01
SELECT CONVERT(decimal(18,2), LEFT(#val,LEN(#val) - 2) + '.' +
RIGHT(#val, 2)) AS TestValue
This assumes that the values stored always have a decimal point with 2 digits after it.
Both can be done in a single SELECT if required, by substituting REPLACE(#val, '.', '') into the position of #val in the 2 queries.
DECLARE #val AS VARCHAR(20) = '1.223.01'
SELECT CONVERT(DECIMAL(18, 2), REPLACE(#val, '.', '')) AS TestValue
SELECT CONVERT(DECIMAL(18, 2), LEFT(REPLACE(#val, '.', ''),
LEN(REPLACE(#val, '.', '')) - 2) + '.'
+ RIGHT(REPLACE(#val, '.', ''), 2)) AS TestValue

I never heard of that format. Sounds like you have a varchar and not a money type. Here is how you can manipulate it.
First removing all periods. Then dividing by 1 to explain to sql-server that this is a numeric. Then multiply by .01 to change it into a decimal number
SELECT
replace(value, '.', '')/1*.01
FROM (values('1.223.01'),('1.111.223.75'),('0.01')) x(value)
Result:
1223.01
1111223.75
0.01

Related

How to add two time values stored as decimal in SQL Server

I need to add two columns which stores time values as decimals
example:
1.) 8.30+0.32 = 9.02 (output should be 9.03 not 8.62)
The above mentioned example is working fine and is an actual output of the below SQL.
I wrote the below SQL which works fine predominantly, but I find few cases where the addition is not proper
Example: 3.57+5.25=18.44
SELECT
case when B.Column_B is null then A.Column_A
when B.Column_B is not null then
replace(CONVERT(varchar(5),
DATEADD(ss,(SUM((DATEPART(hh, replace(isnull(a.Column_A,0.00),'.',':'))*3600) + (DATEPART(mi,replace(isnull(a.Column_A,0.00),'.',':'))*60)) +
SUM((DATEPART(hh, replace(isnull(b.Column_B,0.00),'.',':'))*3600) + (DATEPART(mi,replace(isnull(b.Column_B,0.00),'.',':'))*60))),0),108) ,':','.')
End as "Total_Hours"
I am not able to find where this is going wrong in the above mentioned case. Is there anything wrong here or is there any better way of handling this addition
Try this:
DECLARE #Value01 DECIMAL(9,2) = 8.30
,#value02 DECIMAL(9,2) = 0.32;
SELECT CONCAT
(
(DATEDIFF(MINUTE, '0:00:00', CAST(REPLACE(#Value01, '.', ':') AS TIME)) + DATEDIFF(MINUTE, '0:00:00', CAST(REPLACE(#value02, '.', ':') AS TIME))) / 60
,'.'
,RIGHT((DATEDIFF(MINUTE, '0:00:00', CAST(REPLACE(#Value01, '.', ':') AS TIME)) + DATEDIFF(MINUTE, '0:00:00', CAST(REPLACE(#value02, '.', ':') AS TIME))) % 60 + 100, 2)
);
First, convert to TIME and get the total number of minutes. Then, format the minutes to Time but using . instead :.
Code
declare #v1 DECIMAL(9,3) = 4.369, -- 9 characters with 3 decimal places.
#v2 DECIMAL(9,3) = 3.368 -- 9 characters with 3 decimal places.
print #v1 + #v2
Output
7.737

How can I count number of digits after decimal point

How can I count the number of digits after decimal point in SQL Server 2008?
Eg: 1.99999999495049E-05
I need to know how many digits there are after the decimal point.
If you want to count the number of digits after decimal then the below query works fine.
SELECT LEN(SUBSTRING(cast(COLUMNNAME as varchar), CHARINDEX('.',COLUMNNAME ) + 1, 1000)) AS DIGITSAFTERDECIMALPOINTS
FROM TABLENAME
Hope this helps!
Wow, that's superbly tricky. This sort of logic should get you there:
DECLARE #Value float(53) = 1.99999999495049E-5;
DECLARE #StringValue varchar(40) = CONVERT(varchar(40), #Value, 2);
DECLARE #ELocation int = CHARINDEX('e', #StringValue);
DECLARE #ExponentDigits int = 0 - CAST(SUBSTRING(#StringValue, #Elocation + 1, 40) AS int);
DECLARE #MantissaString varchar(40) = REPLACE(SUBSTRING(#StringValue, 1, #ELocation - 1), '.', '');
DECLARE #NumberOfMantissaDigits int = LEN(CAST(CAST(REVERSE(#MantissaString) AS bigint) AS varchar(20)));
SELECT #ExponentDigits + #NumberOfMantissaDigits - 1 AS NumberOfDecimalPlaces;
I've left them all as separate statements so you can work out what's going on. I could put it all in a single line expression but I'd shudder to try and understand it later.
If you would like to count the number of digits after a decimal point in Teradata
SELECT LENGTH(SUBSTRING(COLUMN_NAME FROM POSITION('.' IN COLUMN_NAME) + 1 FOR 1000))
FROM TABLE

Return 1.23 from 1.2.3 in SQL?

I want to get the value 1.23 from 1.2.3.Similar, I also get the value 1.2.3...x from 1.2.3...x .How can I do this in SQL?
After I get number from string in this topic: How to get number from String sql
Now, this value is 1.2.3. When i cast, sql notice an error: "Error converting data type nvarchar to float" And i want to return the value 1.23 from 1.2.3
you can also use a combination of STUFF and REPLACE and CHARINDEX to achieve what you require. The solution saves the first location of . , replaces all the other decimal points and then stuffs it back in. Something like this
;WITH CTE AS
(
SELECT '1.23' as CharCol
UNION ALL SELECT '6.7.1.'
UNION ALL SELECT '4.2.3'
UNION ALL SELECT '1.46'
UNION ALL SELECT '5.43'
UNION ALL SELECT '90'
)
SELECT
CASE WHEN CHARINDEX('.',CharCol) = 0
THEN CharCol
ELSE STUFF(REPLACE(CharCol,'.',''),CHARINDEX('.',CharCol),0,'.')
END
FROM CTE;
You can use an ugly combination of SUBSTRING, REPLACE and PATINDEX. Something like
SELECT
SUBSTRING(a, 1, PATINDEX('%.%', a) - 1) AS pre
,REPLACE(SUBSTRING(a, PATINDEX('%.%', a), LEN(a)), '.', '') AS post
,SUBSTRING(a, 1, PATINDEX('%.%', a) - 1) + '.' + REPLACE(SUBSTRING(a, PATINDEX('%.%', a), LEN(a)), '.', '') AS result
FROM (
SELECT
'1.2.3' AS a
) I
The pre and post columns are the two halves, appended them with a '.' in the result column.
The number before the first '.' will remain before, while any numbers after the the first '.' will be put together after the '.'
e.g.
432.546.3.132.6 = 432.54631326

SQL server convert hex string to varbinary

I have a string column that represents hex values, for example -
'274', '1A7', '3D1' and so on.
Now I need to convert these values to their integer values, so that '10' will be converted to 16, for example.
The code I use:
SELECT CONVERT(int, CONVERT(varbinary, '0x' + case when replicate('0', len(myHex) / 2) + myHex = '0' then '00' else replicate('0', len(myHex) / 2) + myHex end, 1))
I'm actually padding the string with a zero or two to make it's length even, and adding the '0x' prefix. However some (random) rows fail.
Is there another way to convert the values?
Thanks.
please give feedback
so that i can improve my answer
Here is one way to do it:
//create function fn_HexToIntnt(#str varchar(16))
//returns bigint as begin
select #str=upper(#str)
declare #i int, #len int, #char char(1), #output bigint
select #len=len(#str)
,#i=#len
,#output=case
when #len>0
then 0
end
while (#i>0)
begin
select #char=substring(#str,#i,1), #output=#output
+(ASCII(#char)
-(case
when #char between ‘A’ and ‘F’
then 55
else
case
when #char between ’0′ and ’9′
then 48 end
end))
*power(16.,#len-#i)
,#i=#i-1
end
return #output
end
or
SELECT CONVERT(INT, 0×00000100)
SELECT CONVERT(VARBINARY(8), 256)

Changing values in a varchar column with float conversion

I am working with a table with a column 'value' with the type varchar(100).
All values in that column must be changed by multiplying them with 0.001 but my following update script fails due to "arithmetical overflow error while converting varchar to a numeric type".
update testTable
set value = cast ((value * 0.001) as varchar);
I must not change the type of the column and it holds values between 0 and 4294966796.
How do i cast correctly to get the calculation in the update working?
I tried cast (cast ((value * 0.001)) as float) as varchar) but it still throws the error.
CAST(CAST( value AS NUMERIC) *0.001 AS VARCHAR(100))
Here try this :
update testTable
set value = cast ((cast(value as float) * 0.001) as varchar);
If it still fails then one of the rows have non-numeric value
You can;
update testTable cast(cast(value as decimal) * 0.001 as varchar(32))
One way
update testTable
set value = convert(float,value) * 0.001
A simple example you can run
DECLARE #z varchar(100)
SELECT #z = CONVERT(float,'123') * 0.001
SELECT #z
0.123
If your values exceed the size of a float, then you can do the arithmetic as strings. This is a special case, because multiplying by 0.001 is just moving the decimal place over three places to the left. The following works for values greater than 1000, with or without decimal places:
update testTable
set value = (case when charindex('.', value) = 0
then left(value, len(value) - 3)+'.'+right(value, 3)
else left(value, charidnex('.', value) - 3) + '.' +
replace(right(value, len(value) - charindex('.', value) + 4), '.', '')
end)
If you have values less than 100, then you will need to prepend the values with 0s for this to work.

Resources