Загрузка данных


WITH
src AS (                                   -- дедуп до тяжёлых regexp'ов
    SELECT DISTINCT NAIMEN
    FROM SH.UCH_VSE
    WHERE NAIMEN IS NOT NULL
),
norm AS (
    SELECT
        REGEXP_REPLACE(TRIM(NAIMEN), '[[:space:]]+', ' ')                      AS NAIMEN,
        ' ' || TRIM(REGEXP_REPLACE(UPPER(NAIMEN), '[^А-ЯЁ0-9-]+', ' ')) || ' ' AS TOK
    FROM src
),
clean AS (                                 -- отсев организаций по токенам
    SELECT n.NAIMEN
    FROM norm n
    WHERE NOT EXISTS (
        SELECT 1
        FROM SH.FIO_STOP s
        WHERE (s.MATCH_TYPE = 'WORD'   AND INSTR(n.TOK, ' ' || s.WORD || ' ') > 0)
           OR (s.MATCH_TYPE = 'PREFIX' AND INSTR(n.TOK, ' ' || s.WORD)        > 0)
    )
),
t AS (
    SELECT REGEXP_SUBSTR(
               -- вырезаем ИП/ЧП/КПП 123/ИНН-цифры и т.п. в начале
               REGEXP_REPLACE(NAIMEN,
                   '^((КПП|ПБОЮЛ|ИП|ЧП|ФЛ|ИНДИВИДУАЛЬН[А-ЯЁ]*|ПРЕДПРИНИМАТЕЛЬ[А-ЯЁ]*|[0-9]+) )+',
                   '', 1, 1, 'i'),
               '^[А-ЯЁ][-А-ЯЁ]+'
               || '( [А-ЯЁ]\.? ?[А-ЯЁ]\.'                                  -- Иванов И.И.
               || '| [А-ЯЁ][-А-ЯЁ]+( [А-ЯЁ][-А-ЯЁ]+)?'                      -- Иванов Иван (Иванович)
               ||   '( (ОГЛЫ|ОГЛУ|КЫЗЫ|УГЛИ|УУЛУ|ГИРЕЙ|ХАН|БЕК|БАЙ))?)',
               1, 1, 'i') AS FIO
    FROM clean
),
f AS (
    SELECT DISTINCT FIO
    FROM t
    WHERE FIO IS NOT NULL
      AND REGEXP_LIKE(FIO, '^[А-ЯЁ]', 'c')
      AND LENGTH(FIO) BETWEEN 6 AND 40
      AND LENGTH(REGEXP_SUBSTR(FIO, '^[^ ]+')) > 3          -- вместо {2,3} caps
      AND REGEXP_LIKE(UPPER(REGEXP_SUBSTR(FIO, '^[^ ]+')),
          '(ОВ|ЕВ|ЁВ|ИН|ЫН|ИЙ|ЫЙ|ОЙ|ЯН|ЯНЦ|ЕЦ|ЕНОК|ИЧ|УК|ЮК|АК|ЯК|ИК|ХАН|БЕК|БАЙ|[АЕИОУЮЯ])$')
)
SELECT COUNT(*) OVER () AS Всего_строк, FIO
FROM f
ORDER BY FIO;