REGEXP_COUNT в postgres

Мы переходим с Oracle на Postgres.

вот SQL, где я извлекал данные из столбца employee_name и использовал для отчета.

но теперь я не уверен, как сделать часть regex_count. Oracle SQL

with A4 as 
(
select 'govinda j/INDIA_MH/9975215025' as employee_name from dual
)
select employee_name , 
TRIM(SUBSTR(upper(A4.employee_name),1,INSTR(A4.employee_name,'/',1,1)-1)) AS employee_name1,
  TRIM(SUBSTR(upper(A4.employee_name),INSTR(A4.employee_name,'/',1,1)+1,INSTR(A4.employee_name,'_',1,1)-INSTR(A4.employee_name,'/',1,1)-1)) AS Country,
  TRIM(SUBSTR(upper(A4.employee_name),INSTR(A4.employee_name,'_',1,1)+1,INSTR(A4.employee_name,'/',1,2)-INSTR(A4.employee_name,'_',1,1)-1)) AS STATE,
  CASE WHEN REGEXP_COUNT(A4.employee_name,'_')>1 THEN 'WRONG_NAME>1_'
       WHEN REGEXP_COUNT(A4.employee_name,'/')>2 THEN 'WRONG_NAME>2/'
       WHEN TRIM(SUBSTR(upper(A4.employee_name),INSTR(A4.employee_name,'/',1,1)+1,INSTR(A4.employee_name,'_',1,1)-INSTR(A4.employee_name,'/',1,1)-1))NOT IN
         ('INDIA','NEPAL') THEN 'WRONG_COUNTRY'
       ELSE 'CORRECT' END AS VALIDATION

       from A4

В Postgres с помощью я могу преобразовать его в нижнюю часть.

with A4 as 
(
select 'govinda j/INDIA_MH/9975215025'::text as employee_name
)
select employee_name,
       split_part(employee_name, '/', 1) as employee_name1,
       split_part(split_part(employee_name, '/', 2), '_', 1) as country,
       split_part(split_part(employee_name, '/', 2), '_', 2) as state
from A4

Но часть валидации не может преобразовать . любая помощь приветствуется, так как мы очень плохо знакомы с postgres.


person Mayur Randive    schedule 20.09.2018    source источник


Ответы (1)


Вы можете создать пользовательскую функцию:

create or replace function number_of_chars(text, text)
returns integer language sql immutable as $$
    select length($1) - length(replace($1, $2, ''))
$$; 

Использовать:

with example(str) as (
values 
    ('a_b_c'),
    ('a___b'),
    ('abc')
)

select str, number_of_chars(str, '_') as count
from example

  str  | count  
-------+-------
 a_b_c |     2
 a___b |     3
 abc   |     0
(3 rows)

Обратите внимание, что приведенная выше функция просто подсчитывает количество вхождений символа в строку и не использует регулярные выражения, которые, как правило, обходятся дороже.

Эквивалент regexp_count() в Postgres может выглядеть так:

create or replace function regexp_count(text, text)
returns integer language sql as $$
    select count(m)::int
    from regexp_matches($1, $2, 'g') m
$$; 

with example(str) as (
values 
    ('a_b_c'),
    ('a___b'),
    ('abc')
)

select str, regexp_count(str, '_') as single, regexp_count(str, '__') as double
from example

  str  | single | double 
-------+--------+--------
 a_b_c |      2 |      0
 a___b |      3 |      1
 abc   |      0 |      0
(3 rows)
person klin    schedule 20.09.2018
comment
Функция Oracle regexp_count также принимает еще два параметра pos и match_pattern. Как с этим справиться? - person dr__noob; 11.05.2020