Поиск нескольких строк в нескольких столбцах в ORACLE SQL

У меня есть одна таблица базы данных с информацией о человеке (идентификатор, имя, имя, улица, город...).

Я хочу выполнить поиск по нескольким строкам во всех столбцах, например, моя строка поиска — Mainstreet John Doe.

Теперь я хочу создать запрос выбора (Oracle SQL), который ищет все строки во всех столбцах.

имя имя улица город вернуться из выбора Джон Доу Главная улица Нью-Йорк да Джон Доу улица Нью-Йорк нет Доу Джон Главная улица Нью-Йорк да Главная улица Джон лань Нью-Йорк да

Есть ли способ в Oracle SQL создать такой запрос?

Возможно, вы захотите посмотреть Oracle Text.

MT0 23.04.2024 13:29

По поисковой строке «улица Джона Доу» вы бы вернули только строку №2, верно?

Thorsten Kettner 23.04.2024 13:40

правильно, только строка №2

Supptech 23.04.2024 13:41
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
3
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Учитывая примерные данные:

CREATE TABLE person (fname, lname, street, city, return_from_select ) AS
SELECT 'John',       'Doe',  'mainstreet', 'New York', 'yes' FROM DUAL UNION ALL
SELECT 'John',       'Doe',  'street',     'New York', 'no'  FROM DUAL UNION ALL
SELECT 'Doe',        'John', 'mainstreet', 'New York', 'yes' FROM DUAL UNION ALL
SELECT 'mainstreet', 'John', 'doe',        'New York', 'yes' FROM DUAL;

У вас должна быть возможность создать многостолбцовый индекс Oracle Text:

BEGIN
  ctx_ddl.create_preference('person_lexer', 'BASIC_LEXER');  
  ctx_ddl.set_attribute('person_lexer', 'mixed_case', 'NO'); 

  ctx_ddl.create_preference('person_datastore', 'MULTI_COLUMN_DATASTORE'); 
  ctx_ddl.set_attribute(
    'person_datastore',
    'columns',
    'fname, lname, street, city'
  ); 
END;
/

CREATE INDEX person_idx
  ON person (fname) INDEXTYPE IS CTXSYS.CONTEXT
  PARAMETERS ('datastore person_datastore lexer person_lexer');

Затем используйте запрос:

SELECT *
FROM   person
WHERE  CONTAINS(fname, 'mainstreet AND John AND Doe') > 1

или:

SELECT *
FROM   person
WHERE  CONTAINS(
         fname,
         REPLACE('mainstreet John Doe', ' ', ' AND ')
       ) > 1;

или

SELECT *
FROM   person
WHERE  CONTAINS(
         fname,
         REGEXP_REPLACE('mainstreet John Doe', '\s+', ' AND ')
       ) > 1;

Что все выводит:

ФИМЯ LИМЯ УЛИЦА ГОРОД RETURN_FROM_SELECT Джон Доу Главная улица Нью-Йорк да Доу Джон Главная улица Нью-Йорк да Главная улица Джон лань Нью-Йорк да
Ответ принят как подходящий

Вы можете разбить строку поиска и выполнить поиск по объединенным столбцам для каждого из них:

select *
  from (select p.*,
               '|'||fname||'|'||lname||'|'||street||'|'||city||'|' searchlist
          from person)
 where searchlist like '%|mainstreet|%
   and searchlist like '%|John|%
   and searchlist like '%|Doe|%

Он не будет хорошо работать с большими объемами (поскольку не сможет использовать индекс), но при достаточно скромном размере таблицы будет проще всего.

Если вам нужна скорость при большом объеме, лучше всего создать дочернюю таблицу с каждым словом (fname, lname, street, city и т. д.), которую затем можно будет нормально индексировать и выполнять поиск с предикатом равенства.

спасибо, это решение моей проблемы

Supptech 25.04.2024 14:20

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