Как я могу показать различия между двумя столбцами из разных таблиц с помощью UTL_MATCH в Oracle?

У меня есть два столбца в Oracle DB, которые я хочу сравнить, и если строки отличаются, я хочу показать различия в других столбцах. Я знаю, что что-то скучаю. Так например:

SELECT A.CD_KEY01,
       A.TEXT_01,
       B.TEXT_02,
       UTL_MATCH.edit_distance_similarity(A.TEXT_01, B.TEXT_02) AS distance_similarity
FROM TB_TABLE_01 A 
JOIN TB_TABLE_02 B
ON A.CD_KEY01 = B.CD_KEY02

Пример вывода я получаю:

CD_KEY01  |  TEXT_01              |  TEXT_02               | DISTANCE_SIMILARITY 
   111    |  Superman is good     |  Superman is good      | 100
   222    |  Superman is bad      |  Superman is bad       | 100
   333    |  Superman is handsome |  Hulk is ugly          | 33
   444    |  Superman is awful    |  Batman is awful       | 90

Пример вывода, который мне нужен:

CD_KEY01  |  TEXT_01              |  TEXT_02               | DISTANCE_SIMILARITY | DIFF_01 | DIFF_02 
   111    |  Superman is good     |  Superman is good      | 100                 | NULL    | NULL
   222    |  Superman is bad      |  Superman is bad       | 100                 | NULL    | NULL
   333    |  Superman is handsome |  Hulk is ugly          | 33                  | Hulk    | ugly
   444    |  Superman is awful    |  Batman is awful       | 90                  | Batman  | NULL

1 ответ

Решение

Я сомневаюсь, что есть простой способ. Один из способов - каким-то образом разделить строки на слова (рекурсивный способ ниже), пословно сравнить и получить сводный результат:

with 
  a(key, text_a, word, rn) as (
    select cd_key01, text_01, regexp_substr(text_01, '(\w+)', 1, 1), 1 
      from table_01 
    union all
    select key, text_a, regexp_substr(text_a, '(\w+)', 1, rn + 1), rn + 1 
      from a 
      where regexp_substr(text_a, '(\w+)', 1, rn + 1) is not null),
  b(key, text_b, word, rn) as (
    select cd_key02, text_02, regexp_substr(text_02, '(\w+)', 1, 1), 1 
      from table_02 
    union all
    select key, text_b, regexp_substr(text_b, '(\w+)', 1, rn + 1), rn + 1 
      from b where regexp_substr(text_b, '(\w+)', 1, rn + 1) is not null)
select *
  from (
    select key, rn, text_a, text_b, 
           case when a.word <> b.word then b.word end word 
      from a full join b using (key, rn))
  pivot (max(word) for rn in (1 w1, 2 w2, 3 w3)) order by key

демо

Этот запрос показывает сравнение первых трех слов, isтоже сравнивается. Если в строках может быть разное количество слов, будьте осторожны и изменитеcase when часть обрабатывает нули правильно.

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