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


WITH stop_list AS (
    SELECT ' ' || TRIM(w) || ' ' AS word
    FROM (
        SELECT REGEXP_SUBSTR(s, '[^,]+', 1, LEVEL) AS w
        FROM (
            SELECT REPLACE(REPLACE(
                q'[ООО,ОАО,ПАО,ЗАО,АО,ОДО,ОСБ,АКБ,КБ,ГУП,ГУПУ,МУП,ФГУП,ФУ,КОРПОРЕЙШН,СОФТ,ИНТЕРНЭШНЛ,МЭП,ХОЗ-ВО,РУФПС,
ПАЛАТА,ОАНО,УЗЕЛ,КОНЦЕРН,ФОНД,БАНК,КОМПАНИЯ,ПРЕДПРИЯТИЕ,ОБЩЕСТВО,СОЮЗ,ВКЛАДЫ,ГРАЖДАН,КОРПОРАЦИЯ,КОРПОРАЦИИ,
ИНСТИТУТ,ПОДРАЗДЕЛЕНИЕ,СЕТИ,ОТД,МЕДИА,КЛУБ,РАЙПО,УСИБ,ОБЩ-ВО,ЕДИНЕНИЕ,СКАНСКА,ОТДЕЛЕНИЕ,ПОСОЛЬСТВО,ПОДВОРЬЕ,
КОНСУЛЬТАЦИЯ,СОВЕТ,ФИЛИАЛ,ЗАВОД,ОБЛПО,ГРУППА,СЧЕТ,РЕДАКЦИЯ,НПФ,ГП,ЧАСТЬ,РПЦ,ПИИ,ЭКСПЕДИЦИЯ,ГОСТИНИЦА,СНГ,
ПАРТИЯ,БЮРО,ЕДИНИЦА,Ф-Л,ТУРИЗМ,УМП,ДОМ,ТОВАРИЩЕСТВО,ФИН,РУПС,МЭИ,ЖСК,ТСЖ,ВДПО,ГМБХ,МИНФИН,МИНИФИН,РОС-Я,АРТЕЛЬ,ТЭЛСИС, ОПХ,ТЕПЛОВЫХ,
СИСТЕМС,СОДЕКСО,З-Д,Ф-Т,ЛИМИТЕД,ГОС,НЕФТЕБАЗА,ВЭИ,КОМБИНАТ,КООПЕРАТИВ,ДИСТАНЦИЯ,ЖИЛЬЕ,ЛИЦО,ЛИЦА,ХОЗЯЙСТВО,АВТОШКОЛА, ФРИДАС,
УЧАСТОК,ШАХТА,ИСТЕРН,ПССП,ОТКРЫТОЕ,ЗАКРЫТОЕ,АКЦИОНЕРНОЕ,ГОРОД,ГОРОДА,ПО,МФ,ДОАО,ГПИНЖ,ПСЖА,ФИО,
УЧРЕЖДЕНИЕ,УЧРЕЖДЕНИЯ,УЧРЕЖДЕНИЙ,ФЕДЕРАЛЬНОЕ,ФЕДЕРАЛЬНОЙ,ФЕДЕРАЛЬНЫЙ,ФЕДЕРАЛЬНАЯ,КАЗЕННОЕ,КАЗЕННЫЙ,КАЗЕННАЯ,
УНИТАРНОЕ,УНИТАРНО,УНИТАРНЫЙ,РЕГИОНАЛЬНОЕ,РЕГИОНАЛЬНЫЙ,РЕГИОНАЛЬНАЯ,КРАЕВОЕ,КРАЕВОЙ,ОБЛАСТНОЕ,ОБЛАСТНОЙ,
МУНИЦИПАЛЬНОЕ,МУНИЦИПАЛЬНЫЙ,ГОСУДАРСТВЕННОЕ,ГОСУДАРСТВЕННЫЙ,БЮДЖЕТНОЕ,БЮДЖЕТНЫЙ,АВТОНОМНОЕ,АВТОНОМНЫЙ,
КУЛЬТУРЫ,КУЛЬТУРА,ЛИПЕЦКОЕ,ЛИПЕЦКИЙ,ЛИПЕЦКАЯ,МОРСКАЯ,МОРСКОЙ,УПРАВЛЕНИЕ,ПЕНСИОННОГО,ПЕНСИОННЫЙ,ПЕНСИОННАЯ,
ПОЧТОВОЙ,ПОЧТОВАЯ,ФГУ,ФГУП,ФГБУ,ДЭП,МЗУ,ЭЛЕКТРОПРИБОР,БРЯНСКОЕ,КАЛУЖСКОЕ,ОТДЕЛЕНИЕ]', CHR(10)), CHR(13)) AS s FROM DUAL
        )
        CONNECT BY LEVEL <= REGEXP_COUNT(s, ',') + 1
        UNION ALL
        SELECT REGEXP_SUBSTR(s, '[^,]+', 1, LEVEL) AS w
        FROM (
            SELECT REPLACE(REPLACE(
                q'[НЕВЫЯСНЕ,ПАРТНЕР,ОБЪЕДИ,ОБЪЕД-,АДМИНИСТРА,УПРАВЛЕНИ,ДЕПАРТАМЕНТ,КОМИТЕТ,МИНИСТЕРСТВ,ПОЛИТИЧ,ПРЕДСТАВИТ,
ФЕДЕРАЛЬН,ГОСУДАРСТВЕНН,МЕЖДУНАРОДН,ОРГАНИЗАЦИ,ПРОИЗВОДСТВЕН,ПРОИЗВОД,РАЙОН,ПТИЦЕФАБРИК,ФАБРИК,ЗАКРЫТ,ОТКРЫТ,АКЦИОНЕРН,
МАШИНОСТРО,ГОРОДСК,СЕВЕРН,СЕВЕРО,ЮЖНО-,ЦЕНТР,ФИРМ,ГЛАВН,УПРАВ,ОБЩЕСТ,КОМПАНИ,МУНИЦИПАЛЬН,ДЕТСК,ТЕАТР,ТАНЦ,
ДЕЯТЕЛЬН,ОСУЩЕСТВ,ФЕДЕРАЦ,ПРОФСОЮЗ,ФИНУПР,СТАВРОПОЛЬСК,ЧАСОВЕНСК,БРОННИЦК,СТУПИНС,ОБЛАСТ,ДХООО,ШКОЛ,БОЛЬНИЦ,
ПОЛИКЛИНИК,ТОРГОВ,СТРОИТ,УЧРЕЖД,КАЗЕН,УНИТАР,РЕГИОНАЛЬН,КРАЕВ,БЮДЖЕТН,АВТОНОМН,КУЛЬТУР,ЛИПЕЦК,МОРСК,ПЕНСИОН,
ПОЧТОВ,ЭЛЕКТРОПРИБОР,БРЯНСК,КАЛУЖСК,ОТДЕЛЕНИ]', CHR(10)), CHR(13)) AS s FROM DUAL
        )
        CONNECT BY LEVEL <= REGEXP_COUNT(s, ',') + 1
    )
),
src AS (
    SELECT DISTINCT NAIMEN
    FROM SH.UCH_VSE
    WHERE NAIMEN IS NOT NULL
),
norm AS (
    SELECT NAIMEN,
           TRIM(REGEXP_REPLACE(
               TRANSLATE(UPPER(NAIMEN), 'ABCEHKMOPTXY', 'АВСЕНКМОРТХУ'),
               '[.,;[:space:]]+', ' ')) AS R
    FROM src
),
pre AS (
    SELECT NAIMEN, R,
           LTRIM(REGEXP_REPLACE(
             TRIM(REGEXP_REPLACE(' ' || R || ' ',
               '( (ЧАСТН[А-ЯЁ]*|ПРЕДПРИНИМАТЕЛ[А-ЯЁ]*|ПРЕДПР[А-ЯЁ]*\.?|ПР-ЛЬ|ПР-К|ИНДИВИД[А-ЯЁ]*\.?|ИП|ЧП|ПБОЮЛ|ФЛ'
               || '|НОТАРИУС[А-ЯЁ]*|АДВОКАТ[А-ЯЁ]*|КПП|[0-9]+'
               || '|Г\.?\s*[А-ЯЁ-]{4,}|ГОР\.?\s*[А-ЯЁ-]{4,}))+( |$)',
               ' ')),
             '^[^А-ЯЁ0-9]+', '')) AS BODY
    FROM norm
),
x AS (
    SELECT NAIMEN, BODY,
           CASE WHEN BODY <> R THEN 1 ELSE 0 END AS HAS_PREF,
           REGEXP_COUNT(BODY, ' ') + 1 AS WORD_CNT,
           REGEXP_SUBSTR(BODY, '^[А-ЯЁ][-А-ЯЁ]{2,}') AS FIRST_WORD,
           REGEXP_SUBSTR(BODY,
              '^([А-ЯЁ][-А-ЯЁ]{2,} [А-ЯЁ][-А-ЯЁ]+ ([-А-ЯЁ]{2,}(ИЧ|ЫЧ|ВНА|ИЧНА)|[-А-ЯЁ]+ (ОГЛЫ|ОГЛУ|КЫЗЫ|УГЛИ|УУЛУ)))( |$)',
              1, 1, 'c', 1) AS FA,
           NVL(
             REGEXP_SUBSTR(BODY,
               '^([А-ЯЁ][-А-ЯЁ]{2,} ([А-ЯЁ]\. ?[А-ЯЁ]\.?|[А-ЯЁ] [А-ЯЁ]\.?|[А-ЯЁ]\.))( |$)', 1, 1, 'c', 1),
             REGEXP_SUBSTR(BODY,
               '^([А-ЯЁ]\. ?([А-ЯЁ]\. ?)?[А-ЯЁ][-А-ЯЁ]{2,})( |$)', 1, 1, 'c', 1)) AS FB,
           CASE WHEN BODY <> R AND REGEXP_LIKE(BODY, '^[А-ЯЁ][-А-ЯЁ]{3,}$') THEN BODY
                ELSE REGEXP_SUBSTR(BODY, '^([А-ЯЁ][-А-ЯЁ]{2,} [А-ЯЁ][-А-ЯЁ]{2,})( |$)', 1, 1, 'c', 1)
           END AS FC
    FROM pre
),
y AS (
    SELECT x.*,
           CASE WHEN FA IS NOT NULL THEN 'A'
                WHEN FB IS NOT NULL THEN 'B'
                WHEN FC IS NOT NULL
                     AND (HAS_PREF = 1
                          OR (WORD_CNT = 2 AND REGEXP_LIKE(FIRST_WORD,
                                '(ОВ|ЕВ|ЁВ|ИН|ЫН|ИЙ|ЫЙ|ОЙ|ЯН|ЯНЦ|ЕЦ|ЕНОК|ИЧ|УК|ЮК|АК|ЯК|ИК|ЫХ|ИХ|ХАН|БЕК|БАЙ|[АЕИОУЮЯ])$')))
                THEN 'C' END AS TIER,
           COALESCE(FA, FB,
                    CASE WHEN FC IS NOT NULL
                              AND (HAS_PREF = 1
                                   OR (WORD_CNT = 2 AND REGEXP_LIKE(FIRST_WORD,
                                         '(ОВ|ЕВ|ЁВ|IN|ЫН|ИЙ|ЫЙ|ОЙ|ЯН|ЯНЦ|ЕЦ|ЕНОК|ИЧ|УК|ЮК|АК|ЯК|ИК|ЫХ|ИХ|ХАН|БЕК|БАЙ|[АЕИОУЮЯ])$')))
                         THEN FC END) AS FIO
    FROM x
),
z AS (
    SELECT y.*,
           REGEXP_SUBSTR(FIO, '[А-ЯЁ][-А-ЯЁ]{2,}') AS SURN,
           ' ' || TRIM(REGEXP_REPLACE(CASE WHEN TIER = 'C' THEN BODY ELSE FIO END,
                                      '[^А-ЯЁ0-9-]+', ' ')) || ' ' AS TOK
    FROM y
),
joined AS (
    SELECT z.*, sl.word AS STOP_WORD
    FROM z
    LEFT JOIN stop_list sl
      ON INSTR(z.TOK, sl.word) > 0
    WHERE (z.FIO IS NULL OR z.TIER = 'C')
       OR z.FIO IS NOT NULL
),
res AS (
    SELECT j.*,
           CASE WHEN TIER = 'C' AND NOT REGEXP_LIKE(SURN,
             '(ОВ|ЕВ|ЁВ|ИН|ЫН|ИЙ|ЫЙ|ОЙ|ЯН|ЯНЦ|ЕЦ|ЕНОК|ИЧ|УК|ЮК|АК|ЯК|ИК|ЫХ|ИХ|ХАН|БЕК|БАЙ|[АЕИОУЮЯ])$')
                THEN 0 ELSE 1 END AS END_OK
    FROM joined j
),
fin AS (
    SELECT NAIMEN, FIO, TIER, STOP_WORD, FIRST_WORD,
           CASE WHEN FIO IS NULL            THEN '2_НЕ_ФИО: форма'
                WHEN END_OK = 0             THEN '3_НЕ_ФИО: окончание фамилии'
                WHEN STOP_WORD IS NOT NULL  THEN '4_НЕ_ФИО: стоп-слово'
                WHEN EXISTS (SELECT 1 FROM stop_list st WHERE st.word = ' ' || FIRST_WORD || ' ')
                     THEN '4_НЕ_ФИО: стоп-слово (1-е слово)'
                ELSE '1_OK' END AS STATUS
    FROM res
)
SELECT DISTINCT FIO
FROM fin
WHERE STATUS = '1_OK'
ORDER BY FIO;