Decimal numbers and currency formatting in Oracle - sql

select .5 as colm from dual;
gives 0.5 as the output
But
select .5||'$' as colm from dual;
gives .5$ as the result. Why I am not getting 0.5$
How can I achieve 0.5$ in the second query?

Instead of appending, we can do like below. Format the currency in expected format.
select TO_CHAR(.5,'FM999999990.099999999$') as colm from dual;
Otherwise, you still can concat the currency symbol like,
select TO_CHAR(.5,'FM999999990.099999999')||'$' as colm from dual;
Key is you have to explicitly mention the number format before concatenating.
Format models are well-covered in the documentation. Read it here.

Oracle Setup:
CREATE TABLE your_table ( value ) AS
SELECT 0.5 FROM DUAL UNION ALL
SELECT 5 FROM DUAL;
Query:
SELECT value,
REGEXP_REPLACE(
TO_CHAR( value, 'FM9999999990.99' ),
'\.$'
) || '$' AS formatted_value,
CASE
WHEN TRUNC( value ) = value
THEN TO_CHAR( value, '9999999990' )
ELSE TO_CHAR( value, 'FM9999999990.99' )
END || '$' AS alternate_value,
TO_CHAR( value, '9999999990.99L' ) AS currency_value
FROM your_table;
Output:
VALUE FORMATTED_VALUE ALTERNATE_VALUE CURRENCY_VALUE
----- --------------- --------------- --------------
0.5 0.5$ 0.5$ 0.50$
5 5$ 5$ 5.00$

Do you like to write $ as a constant string or is it your local currency symbol (US-Dollars)?
In later case, this solution may work for you:
SELECT TO_CHAR(0.5555, 'fm999999990D99L') from dual;
See TO_CHAR - Number Format Elements:
L
Returns in the specified position the local currency symbol (the
current value of the NLS_CURRENCY parameter).

You cannot concatenate a "NUMBER" field with a String field.
In your case .5 is a number and '$' is a string. So if you want your result to be '0.5$' you have to pass 0.5 as a string as below:-
select '0.5'||'$' as colm from dual;

Related

How to convert a date to a string

I want yo get only the 'date hours:minutes:seconds' from the Date column
Date
10/11/22 12:14:01,807000000
11/12/22 13:15:46,650000000
29/12/22 14:30:46,501000000
and I want to get a string column with date hours:minutes:seconds
Date_string
10/11/22 12:14:01
11/12/22 13:15:46
29/12/22 14:30:46
I tried this code but it doesn't work:
select*, TO_CHAR(extract(hour from (Date)))||':'||TO_CHAR(extract(minute from (Date)))||':'||TO_CHAR(extract(second from (Date))) as Date_string
from table;
If this is a date column, you could use to_char directly:
SELECT m.*, TO_CHAR(my_date_column, 'dd/mm/yy hh24:mi:ss')
FROM mytable m
You can use REGEX SUBSTRING function to get the date string on the left.
SELECT REGEXP_SUBSTR (Date_string, '[^,]+', 1, 1)
AS left_part
FROM Table1;
where ^, means look for chars that are NOT comma on 1st position
and get the first occurrence (on the left)
Result:
LEFT_PART
10/11/22 12:14:01
11/12/22 13:15:46
29/12/22 14:30:46
reference:
https://docs.oracle.com/cd/B12037_01/server.101/b10759/functions116.htm
Just do it with the TO_DATE() and TO_CHAR() function pair, both operating on the Oracle date format strings:
Building the scenario:
-- your input ..
WITH indata(dt) AS (
SELECT '10/11/22 12:14:01,807000000' FROM dual UNION ALL
SELECT '11/12/22 13:15:46,650000000' FROM dual UNION ALL
SELECT '29/12/22 14:30:46,501000000' FROM dual
)
-- end of your input. Real query starts here.
-- Change following comma to "WITH" ..
,
-- Now convert to TIMESTAMP(9) ...
as_ts AS (
SELECT
TO_TIMESTAMP(dt ,'DD/MM/YY HH24:MI:SS,FF9') AS ts
FROM indata
)
SELECT
ts
, CAST(ts AS TIMESTAMP(0)) AS recast -- note: this is rounded
, TO_CHAR(ts,'DD/MM/YY HH24:MI:SS') AS reformatted -- this is truncated
FROM as_ts
Result:
TS
RECAST
REFORMATTED
10-NOV-22 12.14.01.807000000
10-NOV-22 12.14.02
10/11/22 12:14:01
11-DEC-22 13.15.46.650000000
11-DEC-22 13.15.47
11/12/22 13:15:46
29-DEC-22 14.30.46.501000000
29-DEC-22 14.30.47
29/12/22 14:30:46
Going by what you have in your question, it appears that the data in the field Date is a timestamp. This isn't a problem, but the names of the table (TABLE) and field (Date) present some challenges.
In Oracle, TABLE is a reserved word - so to use it as the name of a table it must be quoted by putting it inside double-quotes, as "TABLE". Similarly, Date is a mixed-case identifier and must likewise be quoted (e.g. "Date") every time it's used.
Given the above your query becomes:
SELECT TO_CHAR("Date", 'DD/MM/YY HH24:MI:SS') AS FORMATTED_DATE
FROM "TABLE"
and produces the desired results. db<>fiddle here
Generally, it's best in Oracle to avoid using reserved words as identifiers, and to allow the database to convert all names to upper case - if you do that you don't have to quote the names, and you can refer to them by upper or lower case as the database automatically converts all unquoted names to upper case internally.

Placing a decimal point just before last two digit of a number

I have a query as below
|| LPAD (TRIM (TO_CHAR (RWTEXPT_STD_AMOUNT, 'FM9999999999999D00')), 15, '0')
its giving the result : 000011545467.00
what i need is : 000000115454.67
i have tried 'FM9999999999999D00' and '999999999999D99' but it gives the same results 000011545467.00
what i need is 000000115454.67
Convert your string value to a number, divide it by 100 and then format it:
SELECT TO_CHAR(
TO_NUMBER(RWTEXPT_STD_AMOUNT)/100,
'FM000000000000D00'
) AS result
FROM table_name
Which, for the sample data:
CREATE TABLE table_name (RWTEXPT_STD_AMOUNT) AS
SELECT '000000011545467' FROM DUAL;
Outputs:
RESULT
000000115454.67
fiddle
Just do it this way
Select To_Char(14.5, 'FM000000000000D00') "NMBR" From Dual
--
-- NMBR
-- ----------------
-- 000000000014.50
Put any number of leading zeros within the format. Zero means zero and 9 is a placeholder if there is a number present. Letter D is for decimal point character. You can use G for grouping character too.
Regarding decimals - if your column has integer value like 1467 and you know that last two numbers are decimal numbers then just put 1467/100
Select To_Char(1467/100, 'FM000000000000D00') "NMBR" From Dual
--
-- NMBR
-- ----------------
-- 000000000014.67
Regards...

regex expression where it can extract the number positioned at the semi end in the string

https://dbfiddle.uk/?rdbms=oracle_18&fiddle=94771b6589b01526ad0cf6e5c4d01945
I need help in extracting the number substring from a file name
currently for file format - 'monkey_eats_mango_everyday_202002.txt'
we are doing like this
select regexp_substr('monkey_eats_mango_everyday_202002.txt', '\d+') as parameter12a
from dual;
result-
202002
which in turn used in larger query to get the last date of this date like this
select to_char(last_day(to_date(regexp_substr('monkey_eats_mango_everyday_202002.txt', '\d+'), 'yyyymm')), 'yyyymmdd') as parameter
from dual ;
result-
20200229
Now the file format has changed, so we have - 'donkey_eats_pines_cones_20192301_7771234_everyday_202002.txt'
In this file format there are numbers at other places like 201943_7771234 which can be dates or any random number, so I need regex expression which can extract 202002 from file format
select regexp_substr('donkey_eats_pines_cones_201943_7771234_everyday_202002.txt', '\d+') as parameter12a
from dual;
You can use a \. to anchor your digits match to next to the period in the file name, and then use a capture group around the digits to get just the digits in the output, using the 6th parameter to REGEXP_SUBSTR to indicate that you only want group 1 in the output:
SELECT REGEXP_SUBSTR('donkey_eats_pines_cones_201943_7771234_everyday_202002.txt', '(\d+)\.', 1, 1, NULL, 1) AS parameter12a
FROM dual;
Output:
202002
Demo on dbfiddle
One option is to use nested expressions: inner returns file extension and the date (that precedes that extension), and outer fetches date itself.
SQL> with test (col) as
2 (select 'donkey_eats_pines_cones_201943_7771234_everyday_202002.txt' from dual)
3 select regexp_substr(regexp_substr(col, '\d+.\w+$'), '\d+') result From test
4 /
RESULT
------
202002
SQL>
check this
select reverse(split_part(reverse(r.r ), '.', 2)) from
(
SELECT reverse(split_part(reverse('donkey_eats_pines_cones_20192301_7771234_everyday_202002.txt'), '_', 1)) as r
)as r
ANS :
202002

How to round a number including least significant zeros?

I am trying to execute following SQL query in Oracle
Select round ( 123.50000065 , 4 ) from dual;
Output : 123.5
Required output: 123.5000
Any help is appreciated. ..
You probably want to use to_char with required format:
Below rounds the value to 4 decimal places and formats into the required string:
Select to_char(123.50000065, '999999999990D9999') x from dual;
If you don't want to actually round the number i.e. you just want to truncate after 4 digits, use:
Select to_char(trunc(123.50000065, 4), '999999999990D9999') x from dual;
ROUND ( numeric_expression , length [ ,function ] )
SELECT ROUND(123.9994, 3), ROUND(123.9995, 3);
Output:
123.9990 124.0000
Instead of round(), use to_char() or cast() to a decimal type:
select to_char(val, '999.9999'),
cast(val as decimal(10, 4))
To control the format a number is showed, you can cast it to a string, by applying the right format mask.
Depending on how you need round your input value, one of these could be useful:
with test(x) as (
select 123.50000065 from dual union all
select 123.00004 from dual union all
select 123.00005 from dual union all
select 123.00008 from dual
)
select x,
to_char(x, 'FM99999999.0000'),
to_char(trunc(x, 4), 'FM99999999.0000')
from test ;
result:
X TO_CHAR(X,'FM9 TO_CHAR(TRUNC(
-------------------------- -------------- --------------
123,50000065000 123.5000 123.5000
123,00004000000 123.0000 123.0000
123,00005000000 123.0001 123.0000
123,00008000000 123.0001 123.0000
"Rounding" is a mathematical concept. The value (with your sample input) is 123.5. Mathematically 123.5000 is the same thing as 123.5. They are only different as STRINGS.
One way to display 123.5 as 123.5000 is to wrap round() within to_char(). However, this means you are not able to use it in further computations (actually Oracle will allow you to - it will do an implicit conversion back to number instead of throwing a data type mismatch error, as it should do).
The better way, in most cases, is to address formatting in your client software, like SQL Developer, SQL*Plus, or Toad. Here is how you can do it in SQL*Plus:
SQL> Select round ( 123.50000065 , 4 ) as result from dual;
RESULT
----------
123.5
-- change the format of the numeric column "result"
SQL> column result format 999.0000
SQL> Select round ( 123.50000065 , 4 ) as result from dual;
RESULT
---------
123.5000
I can't see how you got 123.5 from your query. mine results 123.50000000
if I understand correctly, you want your number 4 significant decimal places.
why not try cast
select cast(123.50000065 as numeric(38,4))
output: 123.5000
testing if it rounds off number:
select cast(123.50000065 as numeric(38,6))
output: 123.500001

Using Concat Operator ( || ) the Integer Part of is not shown for floating numbers

When I am writing a SELECT query in Oracle using concat || operator to concatenate a decimal number and a string. Then for values that have integer part as zero is not shown.
But when I am only selecting Number the Integer part is shown.
My SQL Query Structure :-
SELECT
NUMBER_VAL ||
STRING_VAL
FROM MY_TABLE;
for E.g (selecting only Number):-
SELECT 0.1 FROM DUAL;
I am getting Result: 0.01
E.g (Selecting Number and String Concatenated) :-
SELECT 0.01 || 'ABCD' FROM DUAL;
I am Getting Result: .01ABCD
Desired Result: 0.01ABCD
Can anyone help me how can I achieve the desired result.
This is in Addition to Rics Answer .
The Data type of NUMBER_VAL was NUMBER(9,4).
And that's why I had to Use the Format '99990.9999'
Use to_char function and the appropriate number format:
SELECT
to_char(NUMBER_VAL,'0.99') ||
STRING_VAL
FROM MY_TABLE;
You can specify format when converting to string, such as:
SELECT TO_CHAR(0.01, '0.00') || 'ABCD' FROM DUAL;