Классификация имен таблиц, начинающаяся с и заканчивающаяся на в Oracle DB

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

Всего СЛОЕВ 4

  1. ЭТАП СЛОЙ
  2. БАЗОВЫЙ СЛОЙ ХРАНИЛИЩА ДАННЫХ
  3. СЛОЙ ЭДО
  4. МАРТ СЛОЙ

Все приведенные ниже шаблоны относятся только к сценическому слою.

ЭТАПНЫЙ СЛОЙ — "DS_00", "DSC_00", "DSP_00", "DT"

В этой схеме при поиске комбинации шаблонов поиска мне нужно учитывать таблицы, начинающиеся с «DS_00», «DSC_00», «DSP_00», «DT» (приведенные ниже шаблоны) и заканчивающиеся (T, W, W01, W02, W03,W1,W2,W3), поэтому таблица должна быть классифицирована как STANADARD_NAMING_CONV, иначе NON_STANDARD_NAMING_CONV

Т - технический W - рабочие столы

Узор 1

DS_00_to_99 (00_to_99 — это число, определяющее, из какой системы загружается таблица) DS_SYSTEM_NO_TABLENAME_ENDING СИСТЕМНЫЙ_НОМЕР - 00_to_99 TABLENAME - полное имя таблицы ENDING - не во всех случаях таблица классифицируется как (T,W,W01,W02,W03,W1,W2,W3) поэтому диапазон чисел, как указано, от 00 до 99, также одинаков и для других шаблонов 1.

Узор 2

DSC_00_to_99 (00_to_99 — это число, определяющее, из какой системы загружается таблица из исходного кода) DSC_SYSTEM_NO_TABLENAME_ENDING поэтому диапазон чисел, как указано, от 00 до 99, также одинаков и для других шаблонов 2.

Узор 3

DSP_00_to_99 (00_to_99 — это число, определяющее, из какой системы загружается таблица из исходного кода) DS_SYSTEM_NO_TABLENAME_ENDING поэтому диапазон чисел, как указано, от 00 до 99, также одинаков и для других шаблонов 3.

Узор 4

DT_ABC_FHSJ DS_TABLENAME_ENDING поэтому диапазон чисел не применим для этого шаблона

УРОВЕНЬ БАЗОВОГО ХРАНИЛИЩА ДАННЫХ — «DS»

В этой схеме при поиске комбинации шаблонов поиска мне нужно учитывать таблицы, начинающиеся с «DB» и заканчивающиеся (D, F, L, T, W, W01, W02, W03, W1, W2, W3), поэтому таблица должен быть классифицирован как STANADARD_NAMING_CONV, иначе NON_STANDARD_NAMING_CONV

СЛОЙ EDW - 'DE'

В этой схеме при поиске комбинации шаблонов поиска мне нужно учитывать таблицы, начинающиеся с «DB» и заканчивающиеся (D, F, L, T, W, W01, W02, W03, W1, W2, W3), поэтому таблица должны быть классифицированы как STANADARD_NAMING_CONV, иначе NON_STANDARD_NAMING_CONV, и в этом слое есть некоторые другие таблицы, которые начинаются с TBD_, должны быть классифицированы как TO_BE_DROPPED, а TMP_ должны быть классифицированы как TEMPORARY_TABLE

МАРТ СЛОЙ - 'DM'

В этой схеме при поиске комбинации шаблонов поиска мне нужно учитывать таблицы, начинающиеся с «DB» и заканчивающиеся на (D, F, L, T, W, W01, W02, W03, W1, W2, W3, A, AD, AM,AQ,AY), поэтому таблица должна быть классифицирована как STANADARD_NAMING_CONV, иначе NON_STANDARD_NAMING_CONV, и в этом слое есть некоторые другие таблицы, которые начинаются с TBD_, должны быть классифицированы как TO_BE_DROPPED, а TMP_ должны быть классифицированы как TEMPORARY_TABLE.

D - Таблицы размеров
F - Таблицы фактов
L - Таблицы поиска
T - Технические таблицы
W - Рабочие столы
A - сводные таблицы фактов
AD - сводка фактов ежедневно
AM - Ежемесячный сводка фактов
AQ - Ежеквартальная сводка фактов
AY - совокупный факт ежегодно

Запрос 1 — СТАРЫЙ запрос

SELECT owner,
         object_name,
         beginning,
         ending,
         --count(*),
         CASE
         WHEN ( beginning, ending ) IN (
                ( 'DS', 'T' ),
                ( 'DS', 'W' ),
                ( 'DS', 'W01' ),
                ( 'DS', 'W02' ),
                ( 'DS', 'W03' ),
                ( 'DS', 'W1' ),
                ( 'DS', 'W2' ),
                ( 'DS', 'W3' ),
                ( 'DB', 'D' ),
                ( 'DB', 'F' ),
                ( 'DB', 'L' ),
                ( 'DB', 'T' ),
                ( 'DB', 'W' ),
                ( 'DB', 'W01' ),
                ( 'DB', 'W02' ),
                ( 'DB', 'W03' ),
                ( 'DB', 'W1' ),
                ( 'DB', 'W2' ),
                ( 'DB', 'W3' ),
                ( 'DE', 'D' ),
                ( 'DE', 'F' ),
                ( 'DE', 'L' ),
                ( 'DE', 'T' ),
                ( 'DE', 'W' ),
                ( 'DE', 'W01' ),
                ( 'DE', 'W02' ),
                ( 'DE', 'W03' ),
                ( 'DE', 'W1' ),
                ( 'DE', 'W2' ),
                ( 'DE', 'W3' ),
                ( 'DA', 'D' ),
                ( 'DA', 'F' ),
                ( 'DA', 'L' ),
                ( 'DA', 'T' ),
                ( 'DA', 'W' ),
                ( 'DA', 'W01' ),
                ( 'DA', 'W02' ),
                ( 'DA', 'W03' ),
                ( 'DA', 'W1' ),
                ( 'DA', 'W2' ),
                ( 'DA', 'W3' ),
                ( 'DA', 'A' ),
                ( 'DA', 'AD' ),
                ( 'DA', 'AM' ),
                ( 'DA', 'AQ' ),
                ( 'DA', 'AY' )
              )
         THEN 'STANDARD_NAMING_CONVENTION'
         WHEN object_name LIKE 'TBD%'
         THEN 'TO_BE_DROPPED'
         WHEN object_name LIKE 'TMP%'
         THEN 'TEMPORARY_TABLE'
         ELSE 'NON_STANDARD_NAMING_CONVENTION'
         END AS table_classification
  FROM   (
    SELECT owner,       
           object_name,
           CASE first_separator
           WHEN 0
           THEN NULL
           ELSE SUBSTR( object_name, 1, first_separator - 1 )
           END AS beginning,
           CASE last_separator
           WHEN 0
           THEN NULL
           ELSE SUBSTR( object_name, last_separator + 1 )
           END AS ending
    FROM   (
      SELECT owner,       
             object_name,
             INSTR( object_name, '_', 1 )  AS first_separator,
             INSTR( object_name, '_', -1 ) AS last_separator
      FROM   dba_objects
    WHERE  owner in ('DI_STAGE','DI_BDS','DI_EDW','DI_MART')   
      and    object_type='TABLE'
      group by owner,object_name
      order by owner desc 
    )
  );

Запрос 2 – окончательный запрос – выполнено

SELECT OWNER, 
       OBJECT_NAME, 
       REGEXP_REPLACE(OBJECT_NAME, '^([A-Z0-9$]{1,})_([A-Z0-9$]{1,})_.*','\1_\2')AS  BEGINNING, 
       REGEXP_SUBSTR(OBJECT_NAME, '[^_]*$') AS ENDING, 
      CASE 
        WHEN REGEXP_LIKE(OBJECT_NAME, '^D(S[CP]?|T)_.+_(T|(W0?[123]?))$')
       THEN 
         'STANDARD_NAMING_CONVENTION' 
         WHEN REGEXP_LIKE(OBJECT_NAME, '^DB_.+_(D|F|T|W|W1|W2|W3)$')
           THEN 
         'STANDARD_NAMING_CONVENTION' 
         WHEN REGEXP_LIKE(OBJECT_NAME, '^DE_.+_(D|F|L|T|W|W01|W02|W03|W1|W2|W3)$')
      THEN 
         'STANDARD_NAMING_CONVENTION'
         WHEN OBJECT_NAME LIKE 'TBD%' 
        THEN 
            'TO_BE_DROPPED' 
         WHEN OBJECT_NAME LIKE 'TMP%' 
        THEN 'TEMPORARY_TABLE' 
         WHEN REGEXP_LIKE(OBJECT_NAME, '^DM_.+_(D|F|L|T|W|W01|W02|W03|W1|W2|W3|A|AD|AM|AQ|AY)$') 
       THEN 
         'STANDARD_NAMING_CONVENTION' 
         ELSE 'NON_STANDARD_NAMING_CONVENTION' 
       END 
       AS TABLE_CLASSIFICATION 
FROM   DBA_OBJECTS 
WHERE  OWNER IN ('DI_STAGE', 'DI_BDS', 'DI_EDW', 'DI_MART') 
       AND OBJECT_TYPE = 'TABLE' 
GROUP  BY OWNER, 
          OBJECT_NAME 
ORDER  BY OWNER DESC, 
          OBJECT_NAME; 

ОЖИДАЕМЫЕ РЕЗУЛЬТАТЫ - Соответствует

SNO OWNER  OBJECT_NAME       BEGINNING ENDING  TABLE_CLASSIFICATION 
01  DI_BDS DB_PROD_DGGAA_D   DB_PROD   D       STANDARD_NAMING_CONVENTION
02  DI_BDS DB_CUST_DHHA_F    DB_CUST   F       STANDARD_NAMING_CONVENTION
03  DI_BDS DB_DHSHJA_HHSGS_T DB_DHSHJA T       STANDARD_NAMING_CONVENTION
04  DI_BDS DB_DHS_DHHA_W     DB_DHS    W       STANDARD_NAMING_CONVENTION
05  DI_BDS DB_GSG_DHHA_W01   DB_GSG    W01     STANDARD_NAMING_CONVENTION
06  DI_BDS DB_GFS_FHSH_W02   DB_GFS    W02     STANDARD_NAMING_CONVENTION
07  DI_BDS DB_FGS_FHS_W03    DB_FGS    W03     STANDARD_NAMING_CONVENTION
08  DI_BDS DB_DJJ_GSA_W1     DB_DJJ    W1      STANDARD_NAMING_CONVENTION
09  DI_BDS DB_DKS_SJ_W2      DB_DKS    W2      STANDARD_NAMING_CONVENTION
10  DI_BDS DB_DJA_DT_W3      DB_DJA    W3      STANDARD_NAMING_CONVENTION
11  DI_BDS DB_DHH_DG         DB_DHH    DG      NON_STANDARD_NAMING_CONV
12  DI_BDS DB_DNS_DRS_123    DB_DNS    123     NON_STANDARD_NAMING_CONV
13  DI_BDS DB_FHD_DRS_1      DB_FHD    1       NON_STANDARD_NAMING_CONV
14  DI_BDS DB_OKS_DRS_0      DB_OKS    0       NON_STANDARD_NAMING_CONV
15  DI_BDS DB_SKG_DRS_90     DB_SKG    90      NON_STANDARD_NAMING_CONV

Наконец-то сработало

Как вы определяете стандартные и нестандартные имена?

GMB 10.12.2020 18:58

@GMB подробно обновил вопросы, пожалуйста, посмотрите

Data2explore 10.12.2020 19:08
case when regex_like(table_name,'^DB_.+_[DFTW]$') будет соответствовать любому имени, начинающемуся с DB_ и заканчивающемуся на D, F, T или W. Вы можете определить альтернативы с помощью (ABC|DEF|GHI), означающего любое из ABC, DEF или GHI. Вы можете комбинировать и вкладывать их, например. '^DE_.+_([FT]|W0?[123])$'. (? означает ноль или одно появление, + означает одно или несколько.) И так далее. Я предлагаю исследовать синтаксис регулярных выражений.
William Robertson 11.12.2020 01:15

@WilliamRobertson Спасибо за альтернативы, я пробовал, но не смог включить логику в свой код, не могли бы вы обновить запрос?

Data2explore 11.12.2020 07:49

Кстати, правило, согласно которому все таблицы, принадлежащие DWH_STAGE_LAYER, должны иметь префикс DS_ и т. д., мне кажется немного бессмысленным. Обязательные префикс DWH_ и суффикс _LAYER для всех имен схем, похоже, также не приносят особой пользы. Разве они не могли быть просто STAGE, EDW и DATAMART? Или, поскольку все таблицы в любом случае имеют префиксы, просто иметь одну схему, упрощая код, поддержку и развертывание? Иногда я задаюсь вопросом, действительно ли разработчики многосхемных схем понимают схемы.

William Robertson 12.12.2020 00:03

Кроме того, ваши примеры не включают имя схемы. DE_PROD_RECORD_D отображается как «стандартный», но он был бы нестандартным, если бы принадлежал DWH_STAGE_LAYER.

William Robertson 12.12.2020 01:13

@WilliamRobertson - Большое спасибо за логику, теперь я исправил свой вопрос с объяснением, см. Раздел «Исправленное и обновленное описание с примерами и ожидаемым результатом».

Data2explore 12.12.2020 23:57

Кажется, что требования и соответствующие списки примеров становятся все длиннее. Ключевыми переменными являются схема, префикс и суффикс. Можно ли обобщить эти правила менее чем в 450 строк?

William Robertson 13.12.2020 01:58

@WilliamRobertson - я реконструировал вопрос с объявлением ожидаемых результатов, также я попытался использовать НОВЫЙ ЗАПРОС, можете ли вы предложить

Data2explore 13.12.2020 11:50

Не рекомендуется форматировать текст как код, потому что он просто становится одной длинной строкой, которую труднее читать. Фактические имена схем кажутся частью логики, но до сих пор неясно, что это такое и какое из них соответствует каждому из четырех шаблонов. Мы не знаем, что такое «слой». Я все еще думаю, что мой ответ решает проблему в принципе, хотя может потребоваться одно или два дополнительных условия или измененное регулярное выражение.

William Robertson 13.12.2020 12:01

@WilliamRobertson, я обновил примечание, 4 шаблона входят только в схему этапа.

Data2explore 13.12.2020 12:05

@WilliamRobertson - я тоже близок к моему решению, но я не знаю, как исключить таблицу, оканчивающуюся цифрами 0-9, я отфильтровал одну схему, чтобы уменьшить отображение для облегчения понимания, можете ли вы предложить?

Data2explore 13.12.2020 18:39
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
12
388
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Кажется, вы хотите что-то вроде:

SELECT owner,
       object_name,
       beginning,
       ending,
       CASE
       WHEN ( beginning, ending ) IN (
              ( 'DS', 'INS' ),
              ( 'DE', 'D' ),
              ( 'DE', 'T' ),
              ( 'DM', 'F' ),
              ( 'DM', 'W' ),
              ( 'DM', 'A' ),
              ( 'DM', 'AD' ),
              ( 'DM', 'AM' ),
              ( 'DM', 'AQ' ),
              ( 'DM', 'AY' )
            )
       THEN 'STANDARD_NAMING_CONVENTION'
       WHEN object_name LIKE 'TBD%'
       THEN 'TO_BE_DROPPED'
       ELSE 'NON_STANDARD_NAMING_CONVENTION'
       END AS table_classification
FROM   (
  SELECT owner,       
         object_name,
         CASE first_separator
         WHEN 0
         THEN NULL
         ELSE SUBSTR( object_name, 1, first_separator - 1 )
         END AS beginning,
         CASE last_separator
         WHEN 0
         THEN NULL
         ELSE SUBSTR( object_name, last_separator + 1 )
         END AS ending
  FROM   (
    SELECT owner,       
           object_name,
           INSTR( object_name, '_', 1 )  AS first_separator,
           INSTR( object_name, '_', -1 ) AS last_separator
    FROM   dba_objects
    WHERE  owner in ('DWH_STAGE_LAYER','DWH_EDW_LAYER','DWH_DATAMART_LAYER')  
    AND    object_type='TABLE'
  )
);

@rakesh Обновлено, чтобы удалить лишнюю запятую из списка IN.

MT0 10.12.2020 19:26

Добавьте еще одно условие WHEN к оператору CASE.

MT0 10.12.2020 22:05

Просто сопоставьте DS, а затем концовку. Кроме того, StackOverflow не является сервисом для написания кода. Такие мелочи, как добавление еще одного условия в оператор CASE, — это вещи, которые вы должны уметь решать; если у вас есть проблемы, вы можете задать новый вопрос, а не постоянно ползать по требованиям существующего вопроса, но вы должны убедиться, что, когда вы спрашиваете, вы используете минимально воспроизводимый пример.

MT0 11.12.2020 11:03

Я обновил запрос, а также желаемый результат, не могли бы вы предложить?

Data2explore 11.12.2020 11:32

Мой код уже соответствует паре DS/INS. Если вы хотите сопоставить больше, просто добавьте дополнительные условия в оператор CASE.

MT0 11.12.2020 11:35

нет, я говорю, что у меня есть таблица, начинающаяся с DS_00_CUST_INS - в этих случаях окончание не должно рассматриваться, и результат должен отображаться как STANDARD_TABLE, но ('DS', 'T'), ('DS', 'W'), ('DS', 'W01'), ('DS', 'W02'), ('DS', 'W03'), ('DS', 'W1'), ('DS', 'W2'), ('DS', 'W3'), для этих комбинаций только данные отображаются как стандартные, поэтому таблицы, которые не начинаются с DS_00 до DS_99 (диапазон), мы также должны рассматривать как STANDARD_TABLES (действительные таблицы)

Data2explore 11.12.2020 11:44

Большое спасибо за прохождение логики, наконец-то это сработало для меня

Data2explore 13.12.2020 20:32
Ответ принят как подходящий

Похоже, что это проблема сопоставления шаблонов, но шаблоны также зависят от владельца таблицы. Я делаю это примерно так:

with test (owner, table_name) as
     ( select 'DWH_STAGE_LAYER',    'DS_WHATEVER' from dual union all
       select 'DWH_STAGE_LAYER',    'DS_ANYTHING_F' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_CONS_REV_F' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_CONS_REV_F34' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_ORDER_ENTRY_W' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_ORDER_ENTRY_W12' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_PROC_SALE_A' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_PROC_SALE_A12' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_PROC_SALE_AD' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_PROC_SALE_AD11' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_PROC_SALE_AM' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_PROC_SALE_AQ' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_PROC_SALE_AQ234' from dual union all
       select 'DWH_DATAMART_LAYER', 'DM_WHATEVER_AQ' from dual union all
       select 'DWH_EDW_LAYER',      'DM_WHATEVER_AQ' from dual union all
       select 'DWH_EDW_LAYER',      'DE_EMP_POOL_T' from dual union all
       select 'DWH_EDW_LAYER',      'DE_EMP_POOL_T33' from dual union all
       select 'DWH_EDW_LAYER',      'DE_PROD_RECORD_D' from dual union all
       select 'DWH_EDW_LAYER',      'DE_PROD_RECORD_D123' from dual
     )
select t.owner, t.table_name
     , case
           when t.owner = 'DWH_STAGE_LAYER' and t.table_name like 'DS\_%' escape '\' then 'Y'
           when t.owner = 'DWH_EDW_LAYER' and regexp_like(t.table_name,'^DE_.+_[DFLTW]$') then 'Y'
           when t.owner = 'DWH_DATAMART_LAYER' and regexp_like(t.table_name,'^DM_.+_([DFLTW]|A[DMQY]?)$') then 'Y'
           else 'N'
       end as valid
from   test t
order by t.owner, t.table_name
ВЛАДЕЛЕЦ ТАБЛИЦА_ИМЯ ДЕЙСТВИТЕЛЬНЫЙ DWH_DATAMART_LAYER DM_CONS_REV_F Д DWH_DATAMART_LAYER DM_CONS_REV_F34 Н DWH_DATAMART_LAYER DM_ORDER_ENTRY_W Д DWH_DATAMART_LAYER DM_ORDER_ENTRY_W12 Н DWH_DATAMART_LAYER DM_PROC_SALE_A Д DWH_DATAMART_LAYER DM_PROC_SALE_A12 Н DWH_DATAMART_LAYER DM_PROC_SALE_AD Д DWH_DATAMART_LAYER DM_PROC_SALE_AD11 Н DWH_DATAMART_LAYER DM_PROC_SALE_AM Д DWH_DATAMART_LAYER DM_PROC_SALE_AQ Д DWH_DATAMART_LAYER DM_PROC_SALE_AQ234 Н DWH_DATAMART_LAYER DM_WHATEVER_AQ Д DWH_EDW_LAYER DE_EMP_POOL_T Д DWH_EDW_LAYER DE_EMP_POOL_T33 Н DWH_EDW_LAYER DE_PROD_RECORD_D Д DWH_EDW_LAYER DE_PROD_RECORD_D123 Н DWH_EDW_LAYER DM_WHATEVER_AQ Н DWH_STAGE_LAYER DS_ANYTHING_F Д DWH_STAGE_LAYER DS_WHATEVER Д

Обратите внимание на следующие комментарии:

Я до сих пор не понимаю ваших бизнес-правил, но регулярное выражение для «Начинается с DS и заканчивается любым из T, W, W01, W02, W03, W1, W2 или W3» можно записать как

^DS_.+_(T|W|W01|W02|W03|W1|W2|W3)$

который можно было бы сжать до

DS_.+_(T|(W0?[123]?))$

Если префикс может быть не только DS, но также DSC или DSP с тем же правилом суффикса, это будет

^DS[CP]?_.+_(T|(W0?[123]?))$

Если мы хотим добавить DT в список, я делаю это:

^D(S[CP]?|T)_.+_(T|(W0?[123]?))$

В качестве альтернативы, если вы хотите разбить префикс и суффикс на отдельные столбцы и использовать списки in для их проверки, я бы сгруппировал их вместе, используя что-то вроде:

case
    when begins_with in ('DS', 'DSC', 'DSP', 'DT') and ends_with in ('T', 'W', 'W01', 'W02', 'W03', 'W1', 'W2' or 'W3') then 'Y'
    when begins_with in ('X', 'Y', 'Z') and ends with in ('BLAH1', 'BLAH2', 'BLAH3') then 'Y'
    when ...
    else 'N'
end as valid

Другие вопросы по теме

Итеративно захватывайте подгруппы регулярных выражений в Scala
Отрицательный взгляд назад не работает должным образом. Как предотвратить захват строки второй группой?
Поиск текста с помощью регулярного выражения NEAR
Регулярное выражение для поиска текста после последнего появления символа до другого
Python Regex: добавьте ограничение, что это НЕ должно быть совпадением, если где-то перед совпадением есть кавычка И где-то после
Как я могу определить правило перезаписи, чтобы принимать также пустую строку в дополнение к a-zA-Z-?
Извлечение всех строк на основе двух столбцов с использованием Regex в postgresql
Почему производительность двух регулярных выражений, использующих группы захвата, сильно различается?
Вытащите студентов, которые получили B в файле, используя регулярное выражение
Очистка телефонных номеров с помощью регулярных выражений