Convert Informatica Functions into Postgres - postgresql

I have a workflows in the Informatica which has Expression RTRIM(LTRIM(EMP_NUM,'0')). This function I want to convert it in to the Postgres query. How can we do that ?
SELECT EMP_NUM, EMP_NAME, EMP_EMAIL FROM TEST.EMPLOYEE
Any pointers ?
Sample Data of EMP_NUM
01000
11
0000176
00090900088
08009345353

To replicate what you show:
select rtrim(ltrim('001000 ', ' 0'));
rtrim
-------
1000
(1 row)
String operators and functions for Postgres:
https://www.postgresql.org/docs/current/functions-string.html
An alternate solution(converts to numeric):
select to_number('01000 ', '99999');
to_number
-----------
1000
(1 row)
https://www.postgresql.org/docs/current/functions-formatting.html
to_number(text, text) numeric convert string to numeric to_number('12,454.8-', '99G999D9S')

Related

Number format equivalent function in PostgreSQL

Trying to format the number as per the given format and culture.
Given:
-4059587.225000, --Value
'#,##0.00;(#,##0.00)' --Format
'en-US' --Culture
Will have many patterns, the given one is for example.
Expected output: (4,059,587.23)
In SQL Server we have format() function, what's the equivalent in PostgreSQL?
My try:
select to_char( -4059587.225000, '#,##0.00;(#,##0.00)' );
Error:
multiple decimal points
Use to_char:
SET lc_numeric = 'en_US';
SELECT translate(to_char(-4059587.225000, '9G999G999D99PRFM'), '<>', '()');
translate
════════════════
(4,059,587.23)
(1 row)
The documentation describes the available formats.
How about:
select
concat( to_char( -4059587.225000, '#,##0.00;' ), to_char( -4059587.225000, '(#,##0.00)' ) );

Converting function instr from Oracle to PostgreSQL (sql only)

I am working on converting something from Oracle to PostgreSQL. In the Oracle file there is a function:
instr(string,substring,starting point,nth location)
Example:
instr(text, '$', 1, 3)
In PostgreSQL this does not exist, so I looked up an equivalent function (4 parameter is important).
I found:
The function strpos(str, sub) in Postgres is equivalent of instr(str, sub) in Oracle. Tried options via split_part (it didn't work out).
I need the same result only with standard functions Postgres (not own function).
Maybe someone will offer options, even redundant in code.
This may be done in pure SQL using string_to_array.
with tab(val) as (
select 'qwe$rty$123$456$78'
union all
select 'qwe$rty$123$'
union all
select '123$456$'
union all
select '123$456'
)
select
val
/*Oracle's signature: instr(string , substring [, position [, occurrence ] ])*/
, case
when
array_length(
string_to_array(substr(val /*string*/, 1 /*position*/), '$' /*substring*/),
1
) <= 3 /*occurrence*/
then 0
else
length(array_to_string((
string_to_array(substr(val /*string*/, 1 /*position*/), '$' /*substring*/)
)[:3/*occurrence*/],
'$'/*substring*/)
) + 1
end as instr
from tab
val
instr
qwe$rty$123$456$78
12
qwe$rty$123$
12
123$456$
0
123$456
0
Postgres: fiddle
Oracle: fiddle

find nth position of a specific character in a string in Postgres

I am running Postgres 9.6
I have a list of various class codes.
Here is:
'What I have' And 'What I Want'
what I have --> what I want.
Equip:Mold --> Equip:Mold
Raw:Resin:TPA --> Raw:Resin
FG --> FG
...
My strategy to accomplish this is to write a user defined function that will find the character count 2nd ':' in my list then use the LEFT function with a LEFT('Raw:Resin:TPA',nthpositionget('Raw:Resin:TPA',':',2))
I tried using the following question to no avail.
Postgres: extract text up to the Nth Character in a String
This overall problem is best handled with regexp_replace():
select regexp_replace('Raw:Resin:TPA', '(^.*:.*):', '\1');
regexp_replace
----------------
Raw:ResinTPA
(1 row)
select regexp_replace('Equip:Mold', '(^.*:.*):', '\1');
regexp_replace
----------------
Equip:Mold
(1 row)
select regexp_replace('FG', '(^.*:.*):', '\1');
regexp_replace
----------------
FG
(1 row)
If you want something that finds the nth occurrence of a substring, then something like this could be made into a function:
with invar as (
select 'Raw:Resin:TPA' as a, ':' as d
)
select case
when length(array_to_string((string_to_array(a, d))[1:2], d)) = length(a) then -1
else length(array_to_string((string_to_array(a, d))[1:2], d)) + 1
end
from invar;

getting formatted column value in postgres

I have a column in my table having values of format:
COURSE_214/MODULE_5825/SUBMODULE_123/..../GOAL_124/ACTIVITY_125.
I need value for goal i.e 124 from goal_124. I am planning to use 'regexp_split_to_array' but don't know how to use elements from array.
I am using postgres 9.2.
You can use split_part like so:
select split_part(split_part('COURSE_214/MODULE_5825/SUBMODULE_123/..../GOAL_124/ACTIVITY_125', '/GOAL_', 2), '/', 1)
i.e.
select split_part(split_part(fieldname, '/GOAL_', 2), '/', 1)
Result:
124
Using json_object():
select json_object(string_to_array(translate(params, '_', '/'), '/'))
from test
json_object
------------------------------------------------------------------------------------------------
{"COURSE" : "214", "MODULE" : "5825", "SUBMODULE" : "123", "GOAL" : "124", "ACTIVITY" : "125"}
(1 row)
select json_object(string_to_array(translate(params, '_', '/'), '/'))->>'GOAL' as goal
from test
goal
------
124
(1 row)
The column has a format suitable for json. I would suggest to change the type of the column to jsonb. The first query may be used as a converter.
After the conversion you would access the parameters in an easy way, e.g.:
select *
from test
where params->>'COURSE' = '214'
and (params->>'GOAL')::int > 120;
Simple select of all GOAL_ parameters (if there are more than one)
select ltrim(elem, 'GOAL_')
from (
select unnest(string_to_array(params, '/')) elem
from test
) sub
where elem like 'GOAL_%'
You may try using regular expressions, getting the string between slashes
select substring(your_column from '^.*/(.*)/.*$') from your_table
If you expect to find in that part the GOAL value, use
select substring(your_column from '/GOAL_(.*)/') from your_table

How to remove the dot in to_char if the number is an integer

I need to perform to_char on a numeric field in postgresql. I am not able to come up with the right format string yet. I would like to get some help.
test=# select to_char(1.2, 'FM9999.9999'), to_char(1, 'FM9999.9999'), to_char(1.2212, 'FM9999.9999');
to_char | to_char | to_char
---------+---------+---------
1.2 | 1. | 1.2212
(1 row)
Basically, I should not have the dot if there is are no places after the decimal places. to_char(1, fstring) should result in 1, but to_char(1.23, fstring) should result in '1.23'. I need the to_char to behave exactly like str() function in python. For instance in python console:
>>> str(1.2)
'1.2'
>>> str(1)
'1'
>>> str(1.23)
'1.23'
closest solution I can find is to use the cast function.
=# select cast(1 as text), cast(1.2 as text), cast(12.3 as text), cast(1.0 as text);
text | text | text | text
------+------+------+------
1 | 1.2 | 12.3 | 1.0
Is there a way to use format string achieve the same. If so, can someone help me with the right format string?
You can create a function:
create function to_ch (value numeric, format text)
returns text language sql as $$
select rtrim(to_char(value, format), '.')
$$;
select to_ch(1.2, 'FM9999.9999'), to_ch(1, 'FM9999.9999'), to_ch(1.2212, 'FM9999.9999');
to_ch | to_ch | to_ch
-------+-------+--------
1.2 | 1 | 1.2212
(1 row)
Variant with predefined format (maybe more handy):
create function to_ch4 (value numeric)
returns text language sql as $$
select rtrim(to_char(value, 'FM9999.9999'), '.')
$$;
select to_ch4(1.2), to_ch4(1), to_ch4(1.2212);
to_ch4 | to_ch4 | to_ch4
--------+--------+--------
1.2 | 1 | 1.2212
(1 row)