Разделите и сравните две строки в Oracle SQL - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть таблица с тремя столбцами, структурированная следующим образом:

+------------------------+------------------------------+--------------+
| left                   | right                        | pattern      |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | Kiki Cola 50 ml bottle       |              |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | 50 ml Kiki Cola bottle       |              |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | Kiki Cola 50 ml              |              |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | Kiki Cola Light bottle 50 ml |              |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | Coca Cola 50 ml bottle       |              |
+------------------------+------------------------------+--------------+

Теперь я хотел бы выполнить Oracle - SQL -запрос, который дает мне шаблон редактирования двух строк Лево и право. Результат должен быть следующим:

+------------------------+------------------------------+--------------+
| left                   | right                        | pattern      |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | Kiki Cola 50 ml bottle       | SAME         |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | 50 ml Kiki Cola bottle       | SWAPPED      |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | Kiki Cola 50 ml              | CONTAINED_IN |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | Kiki Cola Light bottle 50 ml | CONTAINS     |
+------------------------+------------------------------+--------------+
| Kiki Cola 50 ml bottle | Coca Cola 50 ml bottle       | NOT_SAME     |
+------------------------+------------------------------+--------------+ 

Все мои попытки с REGEX_SPLIT и CONNECT BY не увенчались успехом. У вас есть идеи, как решить эту проблему?

Ответы [ 2 ]

2 голосов
/ 20 февраля 2020

Вы можете создать тип данных коллекции:

CREATE TYPE stringlist IS TABLE OF VARCHAR2(200);

И затем разбить строки на коллекции слов и сравнить коллекции:

SELECT left,
       right,
       CASE
       WHEN left = right THEN 'same'
       WHEN left_words = right_words THEN 'swapped'
       WHEN left_words SUBMULTISET OF right_words THEN 'contains'
       WHEN right_words SUBMULTISET OF left_words THEN 'contained in'
       ELSE 'not_same'
       END AS pattern
FROM   (
  SELECT left,
         right,
         ( SELECT CAST(
                    COLLECT( REGEXP_SUBSTR( left, '[^ ]+', 1, LEVEL ) )
                    AS stringlist
                  )
           FROM   DUAL
           CONNECT BY
                  LEVEL <= REGEXP_COUNT( left, '[^ ]+' )
         ) AS left_words,
         ( SELECT CAST(
                    COLLECT( REGEXP_SUBSTR( right, '[^ ]+', 1, LEVEL ) )
                    AS stringlist
                  )
           FROM   DUAL
           CONNECT BY
                  LEVEL <= REGEXP_COUNT( right, '[^ ]+' )
         ) AS right_words
  FROM   test_data t
)

Итак, для ваших тестовых данных:

CREATE TABLE test_data ( left, right ) AS
SELECT 'Kiki Cola 50 ml bottle', 'Kiki Cola 50 ml bottle' FROM DUAL UNION ALL
SELECT 'Kiki Cola 50 ml bottle', '50 ml Kiki Cola bottle' FROM DUAL UNION ALL
SELECT 'Kiki Cola 50 ml bottle', 'Kiki Cola 50 ml' FROM DUAL UNION ALL
SELECT 'Kiki Cola 50 ml bottle', 'Kiki Cola Light 50 ml bottle' FROM DUAL UNION ALL
SELECT 'Kiki Cola 50 ml bottle', 'Coca Cola 50 ml bottle' FROM DUAL;

Вывод запроса:

LEFT                   | RIGHT                        | PATTERN     
:--------------------- | :--------------------------- | :-----------
Kiki Cola 50 ml bottle | Kiki Cola 50 ml bottle       | same        
Kiki Cola 50 ml bottle | 50 ml Kiki Cola bottle       | swapped     
Kiki Cola 50 ml bottle | Kiki Cola 50 ml              | contained in
Kiki Cola 50 ml bottle | Kiki Cola Light 50 ml bottle | contains    
Kiki Cola 50 ml bottle | Coca Cola 50 ml bottle       | not_same    

дБ <> fiddle здесь

1 голос
/ 20 февраля 2020
with t( lt, rt) as (
    select 'Kiki Cola 50 ml bottle', 'Kiki Cola 50 ml bottle' from dual union all
    select 'Kiki Cola 50 ml bottle', '50 ml Kiki Cola bottle' from dual union all
    select 'Kiki Cola 50 ml bottle', 'Kiki Cola 50 ml' from dual union all
    select 'Kiki Cola 50 ml bottle', 'Kiki Cola Light bottle 50 ml' from dual union all
    select 'Kiki Cola 50 ml bottle', 'Coca Cola 50 ml bottle' from dual ),
  q as (select rownum rn, lt, rt, 
               '"'||replace(lt, ' ', '", "')||'"' ltx, 
               '"'||replace(rt, ' ', '", "')||'"' rtx from t )
select rn, lt, rt,
       case when lt = rt           then 'same'
            when fl = 0 and fr = 0 then 'swapped'
            when fl = 1 and fr = 0 then 'contains'
            when fl = 0 and fr = 1 then 'contained in'
            else 'not same'
       end pattern
  from (
    select coalesce(l.rn, r.rn) rn,
           max(case when l.rn is null then 1 else 0 end) fl,
           max(case when r.rn is null then 1 else 0 end) fr
      from      (select rn, trim(column_value) lw from q, xmltable(ltx)) l
      full join (select rn, trim(column_value) rw from q, xmltable(rtx)) r 
        on l.rn = r.rn and l.lw = r.rw
      group by coalesce(l.rn, r.rn))
  join q using (rn)

Результат:

    RN LT                     RT                           PATTERN
------ ---------------------- ---------------------------- ------------
     1 Kiki Cola 50 ml bottle Kiki Cola 50 ml bottle       same
     2 Kiki Cola 50 ml bottle 50 ml Kiki Cola bottle       swapped
     3 Kiki Cola 50 ml bottle Kiki Cola 50 ml              contained in
     4 Kiki Cola 50 ml bottle Kiki Cola Light bottle 50 ml contains
     5 Kiki Cola 50 ml bottle Coca Cola 50 ml bottle       not same

Разделить строку на слова (здесь xml -way, connect by тоже работает или функционировать), выполнить сравнение, используя полное объединение, считать нули, группировать по и показать шаблон, используя case when.

...