Позвольте мне объяснить на простых примерах, в основном у нас есть сложный дизайн соглашений об именах таблиц, по крайней мере, в схеме стадии есть 4 шаблона.
Всего СЛОЕВ 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 подробно обновил вопросы, пожалуйста, посмотрите
case when regex_like(table_name,'^DB_.+_[DFTW]$')
будет соответствовать любому имени, начинающемуся с DB_
и заканчивающемуся на D
, F
, T
или W
. Вы можете определить альтернативы с помощью (ABC|DEF|GHI)
, означающего любое из ABC
, DEF
или GHI
. Вы можете комбинировать и вкладывать их, например. '^DE_.+_([FT]|W0?[123])$'
. (?
означает ноль или одно появление, +
означает одно или несколько.) И так далее. Я предлагаю исследовать синтаксис регулярных выражений.
@WilliamRobertson Спасибо за альтернативы, я пробовал, но не смог включить логику в свой код, не могли бы вы обновить запрос?
Кстати, правило, согласно которому все таблицы, принадлежащие DWH_STAGE_LAYER
, должны иметь префикс DS_
и т. д., мне кажется немного бессмысленным. Обязательные префикс DWH_
и суффикс _LAYER
для всех имен схем, похоже, также не приносят особой пользы. Разве они не могли быть просто STAGE
, EDW
и DATAMART
? Или, поскольку все таблицы в любом случае имеют префиксы, просто иметь одну схему, упрощая код, поддержку и развертывание? Иногда я задаюсь вопросом, действительно ли разработчики многосхемных схем понимают схемы.
Кроме того, ваши примеры не включают имя схемы. DE_PROD_RECORD_D
отображается как «стандартный», но он был бы нестандартным, если бы принадлежал DWH_STAGE_LAYER
.
@WilliamRobertson - Большое спасибо за логику, теперь я исправил свой вопрос с объяснением, см. Раздел «Исправленное и обновленное описание с примерами и ожидаемым результатом».
Кажется, что требования и соответствующие списки примеров становятся все длиннее. Ключевыми переменными являются схема, префикс и суффикс. Можно ли обобщить эти правила менее чем в 450 строк?
@WilliamRobertson - я реконструировал вопрос с объявлением ожидаемых результатов, также я попытался использовать НОВЫЙ ЗАПРОС, можете ли вы предложить
Не рекомендуется форматировать текст как код, потому что он просто становится одной длинной строкой, которую труднее читать. Фактические имена схем кажутся частью логики, но до сих пор неясно, что это такое и какое из них соответствует каждому из четырех шаблонов. Мы не знаем, что такое «слой». Я все еще думаю, что мой ответ решает проблему в принципе, хотя может потребоваться одно или два дополнительных условия или измененное регулярное выражение.
@WilliamRobertson, я обновил примечание, 4 шаблона входят только в схему этапа.
@WilliamRobertson - я тоже близок к моему решению, но я не знаю, как исключить таблицу, оканчивающуюся цифрами 0-9, я отфильтровал одну схему, чтобы уменьшить отображение для облегчения понимания, можете ли вы предложить?
Кажется, вы хотите что-то вроде:
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
.
Добавьте еще одно условие WHEN
к оператору CASE
.
Просто сопоставьте DS
, а затем концовку. Кроме того, StackOverflow не является сервисом для написания кода. Такие мелочи, как добавление еще одного условия в оператор CASE
, — это вещи, которые вы должны уметь решать; если у вас есть проблемы, вы можете задать новый вопрос, а не постоянно ползать по требованиям существующего вопроса, но вы должны убедиться, что, когда вы спрашиваете, вы используете минимально воспроизводимый пример.
Я обновил запрос, а также желаемый результат, не могли бы вы предложить?
Мой код уже соответствует паре DS
/INS
. Если вы хотите сопоставить больше, просто добавьте дополнительные условия в оператор CASE
.
нет, я говорю, что у меня есть таблица, начинающаяся с 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 (действительные таблицы)
Большое спасибо за прохождение логики, наконец-то это сработало для меня
Похоже, что это проблема сопоставления шаблонов, но шаблоны также зависят от владельца таблицы. Я делаю это примерно так:
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
Обратите внимание на следующие комментарии:
Я до сих пор не понимаю ваших бизнес-правил, но регулярное выражение для «Начинается с 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
Как вы определяете стандартные и нестандартные имена?