When Select replacing comma with dot is truncating values - sql

I'm trying to convert a varchar column where decimal separator is ','.
The workaround found was replace comma to dot but SQL Server is automatically rounding it up. See below example:
2018-10-08 -8679.95 -8679,94711560794
select DATA, REPLACE([PL]*1,',','.') , PL from TB_BOOK
Please, anyone know How can a get the value with all decimals?

Your approach to replace , with . is ok.
However on top of it you need to explicitly CAST the string to a number with enough decimals (FLOAT, DECIMAL(p, s), ...).
SELECT DATA, CAST(REPLACE([PL],',','.') AS FLOAT), PL from TB_BOOK

Related

Conversion of decimal separator - DB2 SQL

I want to convert a double value column in DB2 SQL with ',' comma decimal separator to '.' dot decimal separator. My local settings are German. I can't change the DB settings since many applications are involved.
Eg : column value =0,81234 I want it to be displayed as 0.81234.
SELECT CAST(CAST(COLUMNNAME AS DECIMAL(8,2)) AS VARCHAR(25))
I tried converting it to decimal(8,2) first and then to varchar. This results in 0.81 (with '.' as expected). But I need all the numbers right of the decimal separator like 0.81234. So, I tried with decimal(7,6) which results in SQL0413N OVERFLOW OCCURRED DURING NUMBER DATA TYPE CONVERSION error.
Is there any other way to display the decimal separator as '.'?
The separator is not actually stored in the DB for numeric columns.
Configure whatever tool you are using to look at the data to use your separator of choice.
Optionally you can run
set option decmpt = *PERIOD;
before running your select.
if you use JDBC you can modify it by adjusting your Connection string. Just add this
:decimalSeparator=1;
for point as decimal separator or 2 for comma as decimal separator

Format query to show floating decimal in Oracle SQL

I am using Oracle SQL Developer and I have a query in which one of the columns has a number value that I want to divide by 1,000,000 then display to show commas and up to 10 decimal places if the calculate value has any decimal places. I am currently using this query:
to_char(value/1000000, 'FM999,999,990.9999999999') as Millions_Value
The above format gives me commas and retains the number of decimal places I want, but it unfortunately adds a decimal point at the end of whole numbers as well.
Example:
value/1000000 = 33993
formatted value = 33,993.
what I want = 33,993
For a decimal value, I get what I want and need to keep the format
Example:
value/1000000 = 0.158739
formatted value = 0.158739
value/1000000 = 10.82
formatted value = 10.82
And ideas on how to get rid of the decimal for integers?
The easiest way is to use RTRIM, e.g.
RTRIM(to_char(value/1000000, 'FM999,999,990.9999999999'), '.') as Millions_Value
will remove any trailing periods.
EDIT
If you want to get fancy and internationalize it you need to query NLS_SESSION_PARAMETERS to get the decimal separator, use the G (group) and D (decimal) specifiers in the format string, and then trim off any trailing decimal separator characters. Or in other words:
WITH cteData AS (SELECT 123456789.123456789 AS N FROM DUAL UNION ALL
SELECT 123 FROM DUAL),
cteDecimalSeparator AS (SELECT SUBSTR(VALUE, 1, 1) AS DECIMAL_SEPARATOR
FROM NLS_SESSION_PARAMETERS
WHERE PARAMETER = 'NLS_NUMERIC_CHARACTERS')
SELECT TO_CHAR(N, 'FM999G999G990D9999999999') AS OLD_FORMAT,
RTRIM(TO_CHAR(N, 'FM999G999G990D9999999999'), s.DECIMAL_SEPARATOR) AS NEW_FORMAT
FROM cteData d
CROSS JOIN cteDecimalSeparator s
which returns
OLD_FORMAT NEW_FORMAT
123,456,789.123456789 123,456,789.123456789
123. 123
Remember: there's no kill like overkill :-)
Personally, I think it looks good with one trailing 0, so converting your format string to have a 0 after the decimal. But to answer you question, I think you just need to trim it after you convert the number like this:
SELECT TRIM(TRAILING '.' FROM TO_CHAR('345676', 'FM999G999G990D9999999999'))
FROM DUAL;

Formatting a string to 2 decimal places?

I have a number that looks like this:
'0000040000'
How can I turn it into a string that looks like this:
400.00
This should work on numbers like this as well :
1234540067 -> 12345400.67
I suspect it's fair to say you have a string that you would like to format as a number.
If you want to "learn" how to do this, I suggest looking up the convert, cast and format functions for SQL Server and gain some extra knowledge.
I've elected to first convert to a numeric type, divide by 100 and format the output.
This saves the need to trim leading zero's.
select format(convert(numeric(18,2), '0000040001') / 100, '0.00'))
Following SQL expression will first change string to decimal and then convert it back to a string in a required format:
SELECT FORMAT(CAST ('0000040000' AS DECIMAL(12,2))/100,'#.00')
This should work:
select convert(varchar(10), convert(decimal(10, 2), try_convert(int, '0000040000') / 100.0))
Why do you want the value as a string? Does a decimal work for your purposes?
Another method is:
select ltrim(str(try_convert(int, '0000040000') / 100.0, 10, 2))
Or using just string manipulations:
select replace(ltrim(replace(stuff('0000040000', 9, 0, '.'), '0', ' ')), ' ', '0')
This would be more elegant if ltrim() in SQL Server accepted the character to trim (as most other databases allow).
Here are a some possible solutions:
DECLARE #x CHAR(10)='0000040000'
SELECT CONVERT(VARCHAR(11),CONVERT(NUMERIC(10,2),CONVERT(NUMERIC(10),#x)/100))
SELECT CONVERT(VARCHAR(11),CONVERT(NUMERIC(10,2),STUFF(#x,9,0,'.')))
Simple as this:
SELECT ROUND('0000040004', 2, 1)/100;
Tested this with SQL Server 2017. It does not care about the fact that the number is a string, it does math on it just fine. Result of the above is 400.04
Your query is more of mathematical one.
To get the last 2 numbers after decimals, get the remainder of the number by dividing it by 100.
To get the digits, leaving the last 2 digits, divide the number by 100 again.
select convert(varchar,1234540067/100)+'.'+ convert(varchar,1234540067% 100);

Convert non numeric values as numeric when they are displayed as numbers

I am using ISNUMERIC to get all non numeric rows in my table - but all I get in return is the following example 1.437.230,61 or 3.511.980,00. I really dont know how to get these few rows converted to numeric! I have conveted about 2,5 mil rows without problem but I am getting about 9000 rows that are not numeric - but as displayed above they are numbers. I have tried to trim my coloumn with no luck!
You should always name the dbms you are using. Many dbms have problems converting proper numbers such as 1.437.230,61 due to the thousand separators. So isnumeric works fine here, but the conversion function doesn't.
Use a string replace function to remove the thousand separators from the string before converting. Such as:
to_number( replace(numstr, '.', '') )

Can't cut and convert a string - weird format

This question is almost the same with one of my previous questions, which can be found HERE
I have a field named: pa_value which keeps varchar records
Now this field contains records like:
0,5582
0,6985
-0,1589
0,9856
-0,6589
I'm getting these results using the following code:
CAST (replace (p7.pa_value ,'%','') AS float (3,0)) as TotalMargin
What I'm trying to do is to remove everything and leave just 5 characters(or 6 if there is a -(minus) infront of the string).
It should be looking like this:
55.82
69.85
-15.89
98.56
-65.89
I tried to cast it as a float and then to convert it to integer. I also tried the floor command, which is not for my case, without any success. I'm always getting a syntax error message. I believe that there is no way to do this
SELECT p7.pa_value=CASE WHEN LEFT( p7.pa_value,1)='-' THEN '-' +
CONVERT(varchar(max),CONVERT(float,substring(p7.pa_value,4,4))/100) ELSE
CONVERT(varchar(max),CONVERT(float,substring(p7.pa_value,3,4))/100) END
FROM <table_name>
What is being done ..
Check if starting character is '-'.
If yes then extract string starting from position 4 else starting
from position 3.
The inner convert function converts string to float for division and
the outer convert changes back the resultant value back to varchar
type.
If you know there are always four digits after the comma, you could use this, though I don't believe it's perfect:
CONVERT(NUMERIC(9,2), REPLACE(REPLACE(p7.pa_value, '%', ''), ',', '')) / 100