How to replace second occurrence of word in postgre sql using SQL? - postgresql

Eg.
select regex_replace('the growth is growth for', '?','good','ig');
it should return
the growth is good for

You can match the word you are looking for, followed by everything up to the 2nd word, followed by the word you are looking for again, then replace it with the first two matches, followed by the word you want to replace it with.
For example:
SELECT regexp_replace(
'the growth is growth for lots of growth',
'(growth)(.*?)(\1)',
'\1\2good', 'ig'
);
regexp_replace
---------------------------------------
the growth is good for lots of growth
(1 row)
Here, the (.*?) is matching everything after the first "growth" text, but to stop matching once it hits the next "growth" text, denoted by \1, meaning whatever was matched in the first group enclosed in parentheses. The ? character makes it non-greedy, matching the minimum needed. If it weren't there, it would match as much as it can, which would keep going if there were more than 2 instances to only replace the last.

Related

PostgreSQL query to find a particular pattern in a text column

I have a text column in my database table which contains values like
A/B
A/B/C
A/B/C/D
A/B/C/D/E
Now, I want to select only those rows where this column value contains maximum three occurrences of '/'.
For clarity - expected output should be:
A/B
A/B/C
A/B/C/D
Can anyone help me with such a query?
I think it would be easier to simply remove everything else and count the number of remaining characters:
where length(regexp_replace(the_column, '[^/]', '', 'g')) <= 3
Online example

Remove last n chars of a varchar column

I wanted to know if there's a "compact" way of deleting last n chars from a column in PostGreSQL.
I have a column born as a DATE formatted like this: yyyy-MM-dd.
I altered the table to make this column a varchar, replaced all of the unnecessary dashes but I can't think about a quick and reliable way to delete the last two chars since I'd like the varchar to show only yyyyMM.
With "quick and reliable" I mean something that won't ask me to use a temp table.
Thanks in advance
Use left(), e.g.:
select
left('20181004', 6), -- get 6 leftmost characters
left('20181004', -2) -- or remove 2 last ones
left | left
--------+--------
201810 | 201810
(1 row)
Just wanted to highlight a version of ewcz's suggestion from a comment
a bit more
substr(myCol, 1, length(myCol) - 2)
as that is more portable across RDMSs (not sure if ANSI though).
E.g. SQLite does not have a LEFT function.
This is also suggested on the followint SQLite question: SQLite trim end characters from string
Tested on PostgreSQL 14, SQLite 3.37.2, Ubuntu 22.04.
Google, index this: "remove suffix".

How to get one letter and one number from REGEX Oracle Sql query

Trying to get just "P1:" from this code but if I add numbers to the one it will output those as well. How do I restrict it to only take numbers 1-9 and have it display "NULL" if it's two digits?
select REGEXP_SUBSTR('P1:EMAIL', '[P]+\d+[:]') as test from dual;
You have included the + operator, which means match one or more of the character or class. If you want to match exactly one then you don't want that. You also don't need the square brackets:
select REGEXP_SUBSTR('P1:EMAIL', 'P\d:') as test from dual;
You might also want to anchor the pattern to the start of the string, but that isn't clear; if so then:
select REGEXP_SUBSTR('P1:EMAIL', '^P\d:') as test from dual;

Pulling a Substring which does not exist in the same position

I am looking to pull a substring from a Oracle database column using PL/SQL.
The column has a large string value which varies in size for different rows. Hence the substring I am referring to will not be in the same position for each row. But the substring is uniquely identifiable. It will be like ",RID!1455,". i.e. It will be preceded by a comma, have RID, followed by a !, followed by a number and then a comma.
I am interested in pulling this number followed by RID. Can you please help me with this. Thank you very much in advance
Consider below query:
Suppose table text1 has column text with string:
dfgggsdRID!3242dfgdfdg
Then below query will give you result '3242':
select substr(text, (select (INSTR(text, 'RID!', 1)+4) FROM text1),4) from text1;

How do I format a number of arbitrary length?

If I have data that includes a numeric column with values into the miillions (eg 63254830038), and I want to format the number as a US Dollar amount (eg. $63,254,830,038), I know I can use:
SELECT numeric_column, to_char(numeric_column, '$999G999G999G999') from table
to format the values, but to do so reliably I either have to include an unnecessarily long text string ('$999G999G999G999') or know the maximum number of possible digits. Is there a way to say, broadly, "group numbers with a comma" instead of explicitly saying "group the hundreds, group the thousands, Oh! and please group the millions"?
You just need cast integer to money type.
E.g.:
tests=> select cast(63254830038 as money);
Or alternative syntax:
tests=> select 6323254830038::money;
And output (I'm from Poland, so money type take my locales and set correct currency symbol):
money
----------------------
63.254.830.038,00 zł
Monetary Types documentation.
You can try something like this (works in sql-server, not sure about postgresql)
select convert(varchar,cast('63254830038' as money),1)
You could do things the hard way using regular expressions: convert the number into a string, reverse it, use regexp_replace to insert commas between pairs of 3 digits, and then reverse it again:
select '$' || reverse(regexp_replace(
reverse(numeric_column::varchar),
E'(\\d\\d\\d)(?=\\d)', '\1,', 'g'))
Explanation
The first argument to regexp_replace is the expression to match, which contains two parts:
(\\d\\d\\d) means 3 digits, which are captured
(?=\\d) is a positive lookahead constraint of a single digit, meaning the match only counts if there is a digit following it. (That is, this digit is checked to exist, but it does not count as part of the match.)
The second argument is what to replace with: the 3 captured digits, plus a comma.
The third argument 'g' is a flag indicating that it should match and replace as many times as possible.
For more information on regular expressions in PostgreSQL, see the documentation.