Oracle Regex grabbing value from key value pair in a string - sql

Consider the following column row:
col
-------------------------
'{"day":"8","every":"2"}'
I am trying to get 8 from this string using regular expression to figure out the day.
so far I have:
SELECT
regexp_replace(col, '{"day":[^0-9]', '') as "day"
FROM
mytable;
This gives me:
day
---------------
8","every":"2"}
I am having trouble figuring out how to filter out the rest of the string from the first number forward. In my example I just want the number 8 for this row.

When you are lucky enough to use Oracle 12c Release 1 (12.1.0.2) or later, do take a look at JSON_VALUE
WITH t (s)
AS (
SELECT '{"day":"8","every":"2"}'
FROM DUAL
)
SELECT JSON_VALUE(s, '$.day' ) AS day
, JSON_VALUE(s, '$.every') AS every
FROM t;
DAY EVERY
--- -----
8 2

How about this?
SELECT
regexp_replace(col, '{"day":"([0-9]+).*', '\1') as "day"
FROM
mytable;

If you don't have access to JSON_VALUE() then I would recommend the following regex unless you always know the position of the day key in the JSON string:
SELECT REGEXP_REPLACE(col, '^.*"day":"(\d+)".*$', '\1') AS day
FROM mytable;
This will replace the entire string (assuming it matches!) with the contents of the first capturing group (enclosed in parentheses: (\d+)). \d indicates a digit 0-9. If you want to return NULL values as well, you can replace \d+ with \d*. If negative or non-numeric values are possible, then I would recommend the following:
SELECT REGEXP_REPLACE(col, '^.*"day":"([^"]*)".*$', '\1') AS day
FROM mytable;
This will return whatever characters that might be contained in the day key.
FYI, once you have the value, numeric or non-, you can convert it to a number safely by using TO_NUMBER() along with REGEXP_SUBSTR():
SELECT COALESCE( TO_NUMBER( REGEXP_SUBSTR( REGEXP_REPLACE( col, '^.*"day":"[^"]*".*$', '\1' ), '\d+' ) ), 0 ) AS day
FROM mytable;
Hope it helps.

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...

ORACLE - select string after 2nd last occurrence of a character ( UNDERSCORE) and before DOT

string: From_the_filename_pick_MONTH_YYYY.csv ,
desired output: MONTH YYYY ,
Tried and achieved result using combination of INSTR , SUBSTR and REPLACE
How can I do this using regular expression?
One method uses regexp_substr():
select replace(regexp_substr('From_the_filename_pick_MONTH_YYYY.csv', '[^_]+_[^._]+[.]'), '.', '')
from dual;

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

Manipulate Data to retrieve specific digit

I have a Table with a Column like this:
Location
19.15
19.14
19.13
18.01
18.02
I searched for function to retrieve just 2 digit from beginning to be like this:
Location
19
19
19
18
18
Unfortunately I can't find solution yet .
select cast(location as int) as location
from your_table
It depends entirely on the data type.
We can return the first two characters of a string column with the SUBSTR() function:
select substr(location, 1, 2) as location
from your_table;
If you wish to handle a varying number of digits before the point then perhaps a regular expression function would be better:
select regexp_substr(location, '([0-9]+)\.(.*)', 1, 1, 'i', 1)) as location
from your_table;
If location is a numeric and you want to remove the trailing decimals you can use TRUNC() like this:
select trunc(location) as location
from your_table;