postgresql : regexp_substr - get sub string between occurrence of delimiters - postgresql

I have these strings:
[{"Name":"id","Value":"Window_Ex_kebklipecbcegiocpa_widget_open"
[{"Name":"id","Value":"Window_Ex_kebklipecbcegiocpa_widget_close"
[{"Name":"id","Value":"Window_Ex_kebklipecbcegiocpa_widget_mid_value"
and I'm trying to extract only the parts after the third _, until the end of the string (which ends always with ")
widget_open
widget_close
widget_mid_value
I'm using postgresql, and wanted to use the regexp_substr syntax, in order to extract it.
Thanks!

regexp_replace(data::text,'^([^_]+_){3}','')
You can try
select regexp_replace(data::text,'^([^_]+_){3}','')
from (
select 'one_two_three_four s'::text as data
union select 'a_bb_ccc_dddd_eeee_ffff'
) data

Related

Redshift how to split a stringified array into separate parts

Say I have a varchar column let's say religions that looks like this: ["Christianity", "Buddhism", "Judaism"] (yes it has a bracket in the string) and I want the string (not array) split into multiple rows like "Christianity", "Buddhism", "Judaism" so it can be used in a WHERE clause.
Eventually I want to use the results of the query in a where clause like this:
SELECT ...
FROM religions
WHERE name in
(
<this subquery>
)
How can one do this?
You can use the function JSON_PARSE to convert the varchar string into an array. Then you can use the strategy described in Convert varchar array to rows in redshift - Stack Overflow to convert the array to separate rows.
You can do the following.
Create a temporary table with sequence of numbers
Using the sequence and split_part function available in redshift, you can split the values based on the numbers generated in the temporary table by doing a cross join.
To replace the double quote and square brackets, you can use the regexp_replace function in Redshift.
create temp table seq as
with recursive numbers(NUMBER) as
(
select 1 UNION ALL
select NUMBER + 1 from numbers where NUMBER < 28
)
select * from numbers;
select regexp_replace(split_part(val,',',seq.number),'[]["]','') as value
from
(select '["christianity","Buddhism","Judaism"]' as val) -- You can select the actual column from the table here.
cross join
seq
where seq.number <= regexp_count(val,'[,]')+1;

Querying part of a string

I am trying to query a column which contains string such as
595.1,N30.10
630.5,E10
I have tried separating the two values into different columns
split_part(code, ',', 1) AS code1,
split_part(code, ',', 2) AS code2
But now I see that some of the rows have 3 (or could be more)
785.59, R57.1, R
I wonder if there is a way to specify and query only the first part of the string without having to split the string. In this case only look for enteries with 595.1,785.59 and ignore the rest.
SELECT distinct ON (id) id,time,year,code
FROM data
where code= ANY('{595.1,785.59}');
I think you already the have logic you need, you only need to thread it together:
SELECT DISTINCT ON (id) id, time, year, code
FROM data
WHERE split_part(code, ',', 1) = ANY('{595.1,785.59}');
This logic appears to be working in the demo below.
Demo
To query on first part of code column you can do like below
SELECT * FROM tableName
WHERE split_part(code, ',', 1) = somevalue

How to get substring from 4th occurence of a character until the end of given string in PSQL

Example
I have a string...
'/this/is/a/given/string/test.file'.
How can I get substring 'given/string/test.file' in PSQL?
Thank you!
You can use a regular expression
with example(str) as (
values('/this/is/a/given/string/test.file')
)
select regexp_replace(str, '(/.*?){4}', '')
from example;
regexp_replace
------------------------
given/string/test.file
(1 row)
or the function string_to_array():
select string_agg(word, '/' order by ord)
from example,
unnest(string_to_array(str, '/')) with ordinality as u(word, ord)
where ord > 4;
Read also How to find the 3rd occurrence of a pattern on a line.
I dont know how to get the nth occurence of a substring, but for this problem, you can use regular expression. Like this:
select substring('/this/is/a/given/string/test.file' from '/[^/]+/[^/]+/[^/]+/(.*)')
You can improve the regular expression, this is just for demo purpose.

PostgreSQL convert a string with commas into an integer

I want to convert a column of type "character varying" that has integers with commas to a regular integer column.
I want to support numbers from '1' to '10,000,000'.
I've tried to use: to_number(fieldname, '999G999G999'), but it only works if the format matches the exact length of the string.
Is there a way to do this that supports from '1' to '10,000,000'?
select replace(fieldname,',','')::numeric ;
To do it the way you originally attempted, which is not advised:
select to_number( fieldname,
regexp_replace( replace(fieldname,',','G') , '[0-9]' ,'9','g')
);
The inner replace changes commas to G. The outer replace changes numbers to 9. This does not factor in decimal or negative numbers.
You can just strip out the commas with the REPLACE() function:
CREATE TABLE Foo
(
Test NUMERIC
);
insert into Foo VALUES (REPLACE('1,234,567', ',', '')::numeric);
select * from Foo; -- Will show 1234567
You can replace the commas by an empty string as suggested, or you could use to_number with the FM prefix, so the query would look like this:
SELECT to_number(my_column, 'FM99G999G999')
There are things to take note:
When using function REPLACE("fieldName", ',', '') on a table, if there are VIEW using the TABLE, that function will not work properly. You must drop the view to use it.

select first letter of different columns in oracle

I want a query which will return a combination of characters and number
Example:
Table name - emp
Columns required - fname,lname,code
If fname=abc and lname=pqr and the row is very first of the table then result should be code = ap001.
For next row it should be like this:
Fname = efg, lname = rst
Code = er002 and likewise.
I know that we can use substr to retrieve first letter of a colume but I don't know how to use it to do with two columns and how to concatenate.
OK. You know you can use substr function. Now, to concatenate you will need a concatenation operator ||. To get the number of row retrieved by your query, you need the rownum pseudocolumn. Perhaps you will also need to use to_char function to format the number. About all those functions and operators you can read in SQL reference. Anyway I think you need something like this (I didn't check it):
select substr(fname, 1, 1) || substr(lname, 1, 1) || to_char(rownum, 'fm009') code
from emp