Снежинка — объединение двух таблиц, где идентификаторы одной таблицы разделены точкой с запятой

#join #snowflake-cloud-data-platform #fuzzy

Вопрос:

Я работаю в Snowflake, и некоторые идентификаторы в данной таблице и столбце разделены точками с запятой. Несмотря на этот разделитель, таблицы все равно должны быть объединены. Любая попытка присоединиться к таблице обычно сталкивается с какой-либо ошибкой.

Ниже у меня есть пример того, что я пытался сделать.

        table_A                       table_B
 ---------- ----------        ---------- ----------  
| some_id  |  F_Name  |      | some_id  |  L_Name  |
 ---------- ----------        ---------- ---------- 
|   12345  |   John   |      |12345;4321|    Doe   |
 ---------- ----------        ---------- ---------- 

Attempted SQL Statement

select table_A.some_id, table_A.F_name, table_B.L_Name
from table_A
left join table_B on table_A.some_id like '%'||table_B.some_id||'%'
 

Источник этой конкретной проблемы обнаружился здесь, но, похоже, он не работает. Возможно, просто невозможно выполнить объединения таким образом.
https://community.snowflake.com/s/question/0D50Z00008zPLLx/join-with-partial-string-match

Любая помощь приветствуется.

Комментарии:

1. В идеале вы не должны пытаться применять функции для объединения предикатов в flight. При этом облачные сервисы Snowflake (или даже индексы на других платформах) не могут обрезать результаты, чтобы обеспечить оптимальное выполнение запроса. Подойдет простая подстрока, но в идеале в данных столбец должен быть уже вложен в строку

Ответ №1:

Ваш подход верен, но ваше использование предложения LIKE — нет. Вы ищете table_A.some_id как частичную часть table_B.some_id

Итак, ваш запрос должен быть :

 WITH table_A AS (
  SELECT '12345' AS some_id, 'John' AS F_NAME
),
table_B AS (
  SELECT '12345;4321' AS some_id, 'Doe' AS L_NAME
)
SELECT 
    table_A.some_id, 
    table_A.F_name, 
    L_Name
FROM table_A
LEFT JOIN table_B 
    ON table_B.some_id LIKE '%'||table_A.some_id||'%'
;
 

введите описание изображения здесь

Комментарии:

1. Большое вам спасибо! Теперь это имеет больше смысла!

Ответ №2:

Если вы используете CTE для выравнивания второй таблицы, а затем отфильтровываете дубликаты

 WITH expand AS (
    SELECT 
       f.seq as seq,
       f.index as index
       f.value as join_token
       t.l_name
    FROM table_b t,
      lateral split_to_table(t.some_id, ';') f
)
SELECT 
  a.some_id, 
  a.f_name, 
  f.l_name
FROM table_a AS a
LEFT JOIN expand AS f
    ON a.some_id = f.join_token
QUALIFY row_number() over (partition by f.seq ORDER BY f.index) == 1