Извлечение и объединение номеров счетов переменной длины из неструктурированных строк с использованием Snowflake

Вопрос или проблема

Проблема:
У меня есть две таблицы в Snowflake: таблица dimension с информацией об аккаунтах и таблица fact, где номера аккаунтов встроены как часть строки в столбце PARAM_VALUE типа строка. Эти строки могут иметь различные форматы и разделители или вовсе не содержать разделителей, что усложняет извлечение номеров аккаунтов для объединения.

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

Таблица измерений содержит данные об аккаунтах:

Таблица измерений (account_dim)

Acc_no
8G4F2H1J9K
4R6T8E3A1L
9W5E2C7R4T
1Q8N6F4G3H
6M9R5E2C1A
3K9P7R4G6T
5E1C8R6T2H
2T4R8G6F1N
7H3G5E2C9R
1L6T8R4E3A
9R5E2C7K3G
4F1N6H8R2T
8G6T4R3E1C
2H5E1C9R7K
6T4R3G6F1N
1C8R6T2H4G
3R5E2C9K7H
5T4R6G1F2E
9K3G5E2C1R
7R4G6T2H1L
Apex Industries
Nova Tech Solutions
Global Finance Corp
Eastern Logistics
Western Digital Inc
Cybernetic Systems
Green Earth Energy
Atlantic Healthcare
Pacific Software
Northern Lights Media
Southern Comfort Foods
Mountain View Ventures
Valley Forge Investments
Oceanic Exploration
Sunset Properties
Cityview Financial
Riverside Manufacturing
Skyline Advertising
Brookside Realty
Lakeside Construction

Таблица фактов содержит миллиарды строк и выглядит так:

Таблица фактов (fact_table)

SQL_ID OBJ_NAME Param_Value
sql_id890890830492hjkhfdjkd899058390245 customer_table (‘TN190423′,’TN80989073’) ,8G4F2H1J9K &niveiui
sql_id234567890123456789012345678901 orders_table 788686786767%9W5E2C7R4T jhjhjgjhg
sql_id987654321098765432109876543210 products_table (‘5T4R6G1F2E’,’4R6T8E3A1L’) AC9879879
sql_id456789012345678901234567890123 shipping_table (‘ Apex Industries
sql_id111111111111111111111111111111 inventory_table ‘ 3K9P7R4G6T,4F1N6H8R2T’ TN0008989
sql_id222222222222222222222222222222 shipping_table (‘9W5E2C7R4T’,’1Q8N6F4G3H’) Eastern Logistics, Riverside Manufacturing jkjkhkj
sql_id333333333333333333333333333333 returns_table ‘6M9R5E2C1A,3K9P7R4G6T’ ‘ 4R6T8E3A1L,’
sql_id444444444444444444444444444444 customers_table (‘5E1C8R6T2H’,’2T4R8G6F1N’) [ 6M9R5E2C1A , 2H5E1C9R7K ]
sql_id555555555555555555555555555555 orders_table ‘7H3G5E2C9R,1L6T8R4E3A’
sql_id666666666666666666666666666666 products_table (‘3K9P7R4G6T’,’7897′)
sql_id777777777777777777777777777777 inventory_table ‘9R5E2C7K3G,4F1N6H8R2T’ &&&8G6T4R3E1C AC8098908,AC465465
sql_id678901234567890123456789012345 customers_table Cityview Financial;; Oceanic Exploration
sql_id789012345678901234567890123456 orders_table TN00098F1NBrookside Realty’
sql_id890123456789012345678901234567 products_table (‘6uyiyiuuitug’,’ 6T4R3G6F1N ‘) Apex Industries

Ожидаемый результат:
Мне нужно извлечь шаблоны из столбца PARAM_VALUE в таблице fact_table с последующим поиском в таблице dim account_dim и разложить их по строкам таблицы фактов, создавая новую таблицу, подобную этой:

SQL_ID OBJ_NAME searched pattern
sql_id890890830492hjkhfdjkd899058390245 customer_table 8G4F2H1J9K
sql_id234567890123456789012345678901 orders_table 9W5E2C7R4T
sql_id987654321098765432109876543210 products_table 5T4R6G1F2E
sql_id987654321098765432109876543210 products_table 4R6T8E3A1L
sql_id456789012345678901234567890123 shipping_table Apex Industries
sql_id456789012345678901234567890123 shipping_table 9K3G5E2C1R
sql_id111111111111111111111111111111 inventory_table 4F1N6H8R2T
sql_id111111111111111111111111111111 inventory_table 3K9P7R4G6T
sql_id222222222222222222222222222222 shipping_table 9W5E2C7R4T
sql_id222222222222222222222222222222 shipping_table 1Q8N6F4G3H
sql_id222222222222222222222222222222 shipping_table Eastern Logistics
sql_id222222222222222222222222222222 shipping_table Riverside Manufacturing
sql_id333333333333333333333333333333 returns_table 6M9R5E2C1A
sql_id333333333333333333333333333333 returns_table 3K9P7R4G6T
sql_id333333333333333333333333333333 returns_table 4R6T8E3A1L
sql_id444444444444444444444444444444 customers_table 5E1C8R6T2H
sql_id444444444444444444444444444444 customers_table 2T4R8G6F1N
sql_id444444444444444444444444444444 customers_table 6M9R5E2C1A
sql_id444444444444444444444444444444 customers_table 2H5E1C9R7K
sql_id555555555555555555555555555555 orders_table 7H3G5E2C9R
sql_id555555555555555555555555555555 orders_table 1L6T8R4E3A
sql_id666666666666666666666666666666 products_table 3K9P7R4G6T
sql_id777777777777777777777777777777 inventory_table 9R5E2C7K3G
sql_id777777777777777777777777777777 inventory_table 4F1N6H8R2T
sql_id777777777777777777777777777777 inventory_table 8G6T4R3E1C
sql_id678901234567890123456789012345 customers_table Cityview Financial
sql_id678901234567890123456789012345 customers_table Oceanic Exploration
sql_id789012345678901234567890123456 orders_table Brookside Realty
sql_id890123456789012345678901234567 products_table Apex Industries
sql_id890123456789012345678901234567 products_table 6T4R3G6F1N

Аккаунты могут иметь разную длину и могут содержать как номер аккаунта, так и его название, и могут адаптироваться к любому формату. Поэтому разделение не должно производиться, так как они могут быть разделены или не разделены и могут использовать любые разделители между ними. Поэтому акцент делается на поиск в таблице измерений.

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

WITH flattened AS (
  SELECT 
    f.sql_id,
    f.obj_name,
    a.Acc_No,
    a.Acc_name
  FROM 
    fact_table f
  JOIN 
    account_dim a ON REGEXP_LIKE(UPPER(f.param_value), UPPER(a.Acc_No))
)
SELECT 
  sql_id,
  obj_name,
  Acc_No,
  Acc_name
FROM 
  flattened;

Ответ или решение

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

Шаги решения

  1. Создать временную таблицу для хранения извлечённых аккаунтов. Мы будем использовать CTE (Common Table Expression) для упрощения извлечения аккаунтов.

  2. Использовать регулярные выражения для поиска номеров аккаунтов. Нам нужно создать регулярное выражение, которое неопределённо найдет номера аккаунтов из PARAM_VALUE, если они находятся в строке.

  3. Объединить извлеченные данные с таблицей измерений. После извлечения аккаунтов, мы объединим их с таблицей account_dim, чтобы получить все соответствующие данные.

Пример запроса

Вот пример SQL-запроса, который можно использовать для решения данной задачи:

WITH extracted_accounts AS (
    SELECT 
        f.sql_id,
        f.obj_name,
        TRIM(value) AS extracted_account
    FROM 
        fact_table f,
        LATERAL FLATTEN(INPUT => REGEXP_SPLIT_TO_ARRAY(UPPER(f.param_value), '[,\'()\\s]+')) AS value
    WHERE 
        TRIM(value) IS NOT NULL AND TRIM(value) <> ''
),
matched_accounts AS (
    SELECT 
        e.sql_id,
        e.obj_name,
        a.Acc_no AS matched_account
    FROM 
        extracted_accounts e
    JOIN 
        account_dim a ON e.extracted_account = UPPER(a.Acc_no)
)
SELECT 
    sql_id,
    obj_name,
    matched_account
FROM 
    matched_accounts
ORDER BY 
    sql_id, obj_name;

Пояснение запроса

  1. extracted_accounts CTE:

    • В этой части запроса мы используем функцию REGEXP_SPLIT_TO_ARRAY, чтобы разбить поле PARAM_VALUE на массив строк, используя различные разделители, такие как запятые, пробелы и скобки.
    • С помощью LATERAL FLATTEN мы преобразуем массив строк в набор строк, что позволит нам извлекать каждое значение отдельно.
    • После этого мы убираем пустые или пробельные значения.
  2. matched_accounts CTE:

    • Здесь мы соединяем извлечённые аккаунты с таблицей account_dim, чтобы найти совпадения по номерам аккаунтов. Мы применяем UPPER() для приведения всех значений к верхнему регистру, чтобы избежать проблем с регистром.
  3. Финальный запрос:
    • В этой части мы выбираем нужные поля из результатов, упорядоченные по sql_id и obj_name.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...