Postgresql decimal point using to_char - sql

I want make a select that adds decimal point into integers, but when I do it, it shows me bunch of # instead of those numbers.
SELECT to_char(1234, '99.99');
What I expected was table with a value of 12.34 but I got ##.## in my select.
However, if I did
SELECT to_char(1234, '99,99');
it showed be 12,34 as expected. Problem is, that I want to have a decimal point and not a comma.
I am using PostgreSQL 13.2

It seems you want to take the last 2 digits and pretend they were decimals. You can't use the predefined . or D formats because they apply to true decimals.
Instead, you can print the dot character (like any other string), between double quotes, before the last 2 digits:
SELECT to_char(1234, '999"."99');
to_char
---------
12.34
PS: on a side note, you are getting the masked output in your 1st query because there isn't enough digit positions on the format:
SELECT to_char(1234, '9999.99');
to_char
----------
1234.00

Welcome to SO. You were very close:) Which locale are you using? Check this example for en_US.UTF-8:
SELECT to_char(1234, '999G99');
to_char
---------
12.34
(1 row)
G: Group separator that uses locale
D: Decimal point that uses locale
Check this tutorial

Related

Leading Zero is getting truncated in Oracle SQL query while doing currency format

Query:
select to_char('0.00', '$999,999,999,999,999.99') from dual;
Actual output:
$.00
Expected Output:
$0.0
Is this what you want?
select to_char('0.00', '$999,999,999,999,990.9') from dual;
The 0 on the first digit forces Oracle to display something, even if the digit is not significant. I also changed the specifier to have just one decimal number instead of two .

Currency column with no decimals: add in decimal

I've been reviewing a currency column that has no decimal spaces. It's an output from a legacy system loaded into our Oracle database.
If the field has three or more numerals it should have a decimal at three spaces right.
If the value has less than three numerals, it should have a decimal and a leading zero.
For example:
2050 should be converted to 2.050
110 should be converted to .110
50 should be converted to .050
I've tried using cast, but I received the error 'invalid datatype.'
It's a basic select statement:
select
customer_id
cast(ENDING_BALANCE as (decimal(10,3)) as Bal_1
from Current_Balances
Any suggestions would be appreciated.
I think you need to cast it to a number and divide by 1000
SELECT CAST(CAST('2050' as INT)/1000 as DECIMAL(10,3)) FROM DUAL
If you really mean to have the output format looking like that, you need to TO_CHAR it
SELECT LTRIM(TO_CHAR(CAST('2050' as INT)/1000, 'FM0.000'), '0') FROM DUAL

Number format in SQL

I have a number for example 39.46
and i want it to convert in ,format i.e it should look like 39,46 in SQL
is there any function to convert decimal amount in , separated format ?
There is a NLS setting NLS_NUMERIC_CHARACTERS, where you can set "," as decimal separator and "." to separate thousands. They are typically automatically set when you set your locale. You obviously use an English locale.
See here.
This assumes you have actual numbers in your DB and not strings which look like numbers. For strings you may want to use sting conversion operations as described by Thomas G.
Below I demonstrate how to use the number format and the nls_numeric_characters parameter, both for a numeric input and a string input. Notice the d (or D) in the format model, it says "use whatever the appropriate decimal separator is."
SQL> select to_char(93.23, '999d99', 'nls_numeric_characters='',.''') from dual;
TO_CHAR
-------
93,23
1 row selected.
Elapsed: 00:00:00.14
SQL> select to_char(to_number('93.23'), '999d99', 'nls_numeric_characters='',.''')
from dual;
TO_CHAR
-------
93,23
1 row selected.

Oracle to_char format number with fill mode (FM0000)

I use the TO_CHAR function to format number from 0001 to 9999, and to fit the column size (VARCHAR2(4)) where the value is inserted (even if value is > 9999).
I use the function like this:
TO_CHAR(n, 'FM0000')
Examples that work:
SELECT TO_CHAR(1, 'FM0000') FROM DUAL;
Result: 0001
SELECT TO_CHAR(1234, 'FM0000') FROM DUAL;
Result: 1234
But when I test with a value greater than 9999, I get an extra character:
SELECT TO_CHAR(12345, 'FM0000') FROM DUAL;
Result: #####
SELECT TO_CHAR(123456, 'FM0000') FROM DUAL;
Result: #####
For information, the result I expected was #### (on 4 chars).
To sum up:
When the value to convert corresponds to the expected size (4), the converted value has the same length (4)
When the value to convert is longer than the expected size (5 or more), the converted value has one more character than the expected length (5).
How to explain this ?
I didn't found explanation in the Oracle documentation here https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i170559
I tried on several Oracle version (9, 10, 11) and the result is the same.
The workaround I found is to truncate the result with RPAD() function RPAD(TO_CHAR(n,'FM0000'), 4) but I need to understand why the TO_CHAR function is not enough.
Your format model still has to allow for the sign of the value. There is no way to indicate to TO_CHAR() that it can never be negative (if that is in fact the case for your values). Even with a 4-digit number the formatting allows allows for five characters, as you can see from the column heading:
SQL> SELECT TO_CHAR(1234, 'FM0000') FROM DUAL;
TO_CH
-----
1234
Notice the column heading is TO_CH, which is five characters, not four. If you have a negative number (as Florin suggested) you need that extra space:
SQL> SELECT TO_CHAR(-1234, 'FM0000') FROM DUAL;
TO_CH
-----
-1234
Without the FM modifier you get a leading space in the returned string for positive values, so LENGTH(TO_CHAR(1234, '0000')) is 5 but LENGTH(TO_CHAR(1234, 'FM0000')) is 4, because the leading space (which normally makes the values in the column right-justified) is suppressed. With a negative value the length of the returned string is 5 either way. The format model determines that the returned data type is varchar2(5) to allow for the sign, even if you know there will never be negative values - there isn't any way for the format model to reflect that.
You can see it with positive values too if you force the sign to be shown:
SQL> SELECT TO_CHAR(1234, 'FMS0000') FROM DUAL;
TO_CH
-----
+1234
There isn't anything you can do about that in the TO_CHAR call. As an alternative to your RPAD workaround, you could use SUBSTR to only get the last four characters of the formatted string:
SQL> SELECT SUBSTR(TO_CHAR(12345, 'FM0000'), -4) FROM DUAL
SUBSTR(TO_CHAR(1
----------------
####
But if you do have negative values you'd lose the sign:
SQL> SELECT SUBSTR(TO_CHAR(-1234, 'FM0000'), -4) FROM DUAL
SUBSTR(TO_CHAR(-
----------------
1234
With your RPAD you keep the sign but lose the fourth significant digit:
SQL> SELECT RPAD(TO_CHAR(-1234, 'FM0000'), 4) FROM DUAL
RPAD(TO_CHAR(-12
----------------
-123
which also isn't good. You may not have to deal with negative numbers; but if you're dealing with number larger than you expect (i.e. you get a number >= 10000 when you're expecting only <= 9999) then I'm not sure you can be certain you won't see an (invalid?) negative number at some point too. This seems to be a data problem rather than a formatting problem, on some level anyway.
Based on your comment to Ollie, another approach which might be more explicit and obvious to future maintainers of the code is to spell it out in a CASE:
SELECT CASE WHEN n BETWEEN 0 AND 9999 THEN TO_CHAR(n, 'FM0000') ELSE '####' END FROM DUAL
Which would also allow you to leave the string column null or use some other magic value rather than ####, if you wanted to.
And another way to trim the value, which may also be clearer, is with CAST:
SQL> SELECT CAST(TO_CHAR(12345, 'FM0000') AS VARCHAR2(4)) FROM DUAL;
CAST
----
####

to_number function in sql

i could not understand why following code
SQL>
Select to_number('1234.64', '9999.9') from Dual;
returns this number 1234.6?is it something like rounding ,truncation or?please help me to understand this code,i know to_number functions,i have used many times this code for simple chars,but here it is not clear anything
This looks a lot like Oracle, but I suspect that the result would be similar in any SQL that used to_number.
The to_number function takes two arguments: the string to be converted to a number, and the format string for the conversion.
In the example, '12345.64' is the string to be converted, while '9999.9' is the format string. In this format string, a 9 stands for a digit while a . stands for the decimal point.
So the function is asking to convert the string '12345.64' to a number with up to 4 digits to the right of the decimal point, and only 1 digit after the decimal point.
The second argument is optional - under normal circumstances, I would omit it.
You should use
SELECT to_number('1234.64', '9999.99') from Dual;
Your mask tells engine you want just one decimal, so number gets rounded.
If you want to get exact number, don't specify any mask:
SELECT to_number('1234.64') from Dual;