Как искать, если строка является подстрокой другой строки того же столбца в Oracle - PullRequest
0 голосов
/ 28 августа 2018

У меня есть таблица, которая содержит миллионы строк для имен клиентов в виде столбца. Я хочу узнать, существует ли часть имени в другой строке в том же столбце. Например. Если строка имеет значение «Роджер Федерер» и есть другие строки со значениями «Роджер» и «Федерер», я хочу соответствующие первичные ключи всех трех строк.

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

Вы можете использовать REGEXP_LIKE

 SELECT * 
    FROM   customers    
    WHERE REGEXP_LIKE (cust_name, 'roger|federer','i')

Демонстрация SQL Fiddle

Дополнительные примеры использования REGEXP_LIKE можно найти здесь

Другим вариантом будет использование ИЛИ

SELECT * 
    FROM   customers    
        WHERE LOWER(cust_name) LIKE LOWER('%roger%')
    OR LOWER(cust_name) LIKE LOWER('%federer%')

Демонстрация SQL Fiddle

Редактировать

При использовании JOIN строка поиска является динамической. Если правильные индексы имеются, то это не окажет большого влияния.

SELECT DISTINCT
   c1.*
FROM
   customers c1 
   JOIN
      customers c2
      ON ( LOWER(c1.cust_name) LIKE LOWER(c2.cust_name || '%') 
      AND c1.cust_id != c2.cust_id)

Демонстрация SQL Fiddle

Редактировать 2

Возможно, что-то вроде ниже

SELECT DISTINCT
   c1.cust_id,
   c1.cust_name,
   CASE
      WHEN
         LOWER(c1.cust_name) LIKE LOWER(c2.cust_name || '%') 
      THEN
         'Matched' 
      ELSE
         'Unmatched' 
   END
   ident 
FROM
   customers c1 
   JOIN
      customers c2 
      ON ( LOWER(c1.cust_name) LIKE LOWER(c2.cust_name || '%') 
      AND c1.cust_id != c2.cust_id)

Демонстрация SQL Fiddle

0 голосов
/ 28 августа 2018

Я думаю, что вы можете использовать объединить одну и ту же таблицу дважды, чтобы получить вывод с запросом ниже,

select a.*, b.* 
  from tab1 a 
      , tab1 b
where ( a.fname like b.fname||'%' or a.lname like b.lname||'%')
  and a.id <> b.id
0 голосов
/ 28 августа 2018

Если вы хотите построить логику, связанную со строками, union концепции могут хорошо подойти,

кстати, в строковых операциях мы бы лучше использовали параметры сортировки с шаблонами через upper или lower функции, чтобы удовлетворить нечувствительность к регистру для букв:

select id from customers where lower(name) like '%roger%' union all
select id from customers where lower(name) like '%federer%';

и нет необходимости добавлять уже включено полное имя (например, Роджер Федерер ).

Редактировать: Альтернативный метод может быть следующим:

  select distinct id
    from (select lower(regexp_substr('&str', '[^[:space:]-]+', 1, 1)) frst,
                 lower(regexp_substr('&str', '[^[:space:]-]+', 1, 2)) lst,
                 lower('&str') nm
            from customers) c1
   cross join customers c2
   where c1.frst like '%' || lower(c2.name) || '%'
      or c1.lst like '%' || lower(c2.name) || '%'
      or c1.nm like '%' || lower(c2.name) || '%';

добавив строку поиска ('&str'), чтобы сделать запрос более динамичным, как вы хотите. (при появлении запроса введите Roger Federer для str переменной подстановки)

...