Как найти похожие слова в описаниях из таблицы

Я хочу найти все строки, содержащие определенные слова в таблице SQL Server.

Допустим, моя таблица называется TableA и имеет следующую структуру:

ID   State            Description
1     LA        Good quality products 
2     NY        Race diversity
3     WA        We are too diverse a group 
4     LA        Environmental problem 
5     LA        Good environment 

У меня также есть другая таблица с именем TableB, в которой есть список слов, которые я хочу найти:

Word

good quality
divers
environment

Что я хочу сделать, так это получить все строки из таблицы A, которые содержат любое из слов в таблице B, а также конкретные ключевые слова, найденные в каждой строке, например:

ID State        Description                                         keywords
1   LA       Good quality products                              good quality
2   NY       Race diversity and environmentally friendly        diversity, environmental
3   WA       We are too diverse a group                         diverse
4   LA       Environmental problem                              Environmental
5   LA       Good environment, good quality                     environment, good quality

Я мог бы использовать '%divers%', если бы данных не было в таблице, но поскольку это так, мне нужно искать слова в таблице.

Я мог бы также использовать «дайвер%», но это может пропустить такие слова, как «разнообразие воздуха», которые я хочу включить.

Если я сделаю '% divers %', может ли он захватить все описания, содержащие это слово, вместо каждого слова?

Для точных совпадений я использовал следующий запрос:

SELECT ID, State, 
        Description, String_Agg(v.Keywords, ', ') AS Keywords
FROM     TableA as A
outer apply (
    select (Trim(value)) t,
        case when exists 
          (select * from tableB as B where lower(B.Word)=lower(Trim(value))) 
        then Trim(value) end Keywords
    from String_Split(Description, ' ')
)v
where Keywords is not null
group by A.ID, A.State, A.Description

Однако я также хочу искать похожие ключевые слова, а не только точные совпадения. Есть ли способ сделать это в SQL Server? Если нет, есть ли аналогичный подход, который я мог бы попробовать?

Использование string_split() означает, что вы сравниваете только отдельные слова и поэтому не найдете фразы в своих ключевых словах, таких как good quality.

AlwaysLearning 17.04.2023 23:40

Что означает «Я мог бы использовать %divers%, если бы данных не было в таблице»? Вы можете выполнять like запросы с подстановочными знаками, даже если данные находятся в таблице (хотя я не уверен, что понимаю ваши требования достаточно, чтобы рекомендовать это).

EdmCoff 17.04.2023 23:42
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
2
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Во-первых, я думаю, что другой ответ полнотекстового поиска предпочтительнее, если он соответствует вашим целям. Однако...

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

WITH cte AS
(
 SELECT id, state, description, word, CHARINDEX(lower(word), lower(description)) pi
 FROM TableA INNER JOIN TableB
  ON CHARINDEX(lower(word), description) > 0
)
, cte2 AS
(
 SELECT cte.*, CHARINDEX(' ', reverse(substring(description, 1, pi))) ps, CHARINDEX(' ', description, pi+len(word)) ns
 FROM cte
)
SELECT id, state, description, STRING_AGG(substring(description, pi - CASE ps WHEN 0 THEN 0 ELSE ps-2 END, CASE ns WHEN 0 THEN len(description) ELSE ns - (pi - CASE ps WHEN 0 THEN 0 ELSE ps-2 END) END), ',')
FROM cte2
GROUP BY id, state, description

Вы можете увидеть, как это работает в этой скрипте.

Идея состоит в том, что первое CTE находит все строки, в которых есть совпадения, и индекс, в котором происходит совпадение. Затем второй CTE находит предыдущий пробел (до совпадения) как ps и новый пробел (после совпадения) как ns). Основной запрос отделяет слова. Нет необходимости использовать CTE, но мне было проще смоделировать. Независимо от того, используете ли вы CTE или нет, вы, вероятно, могли бы немного почистить это.

Ответ принят как подходящий
select id, state, description, string_agg( keyword, ', ') as Keywords
from (
    select distinct id, state, description, 
           case when lower(Trim(value)) like '%'+lower(word)+'%' then trim(value)
                when word like '% %' 
                then substring(description, 
                               charindex(lower(word), lower(description)), 
                               len(word))
           end keyword
    from tablea cross apply string_split(description, ' ')
    join tableb b on description like '%'+word+'%') v
group by id, state, description

дбфиддл

Это решение похоже на ваше, за исключением слов в таблице B, содержащих пробелы, которые требуют специальной обработки.

Спасибо за вашу помощь, и извините за поздний ответ. Это очень похоже на то, что я ищу. Если я ищу 5-ю строку моего идеального результата. В нем есть дополнительная запятая, например, «окружающая среда, хорошее качество». Как мне избавиться от него?

H K 20.04.2023 20:34

Потому что environment, рассматривается как целое слово. Вы можете удалить эти запятые с помощью replace либо на входе, либо на выходе, как в dbfiddle.

Ponder Stibbons 20.04.2023 22:11

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

Похожие вопросы

В сгруппированной таблице, как выбрать идентификатор строки, которая имеет MAX (метка времени) в группе?
Получить следующую и предыдущую строки, упорядоченные по столбцу для подмножества таблицы
Ошибка: P1014 Базовая таблица для модели «клиенты» не существует
Как соединить две таблицы и выбрать строку на основе значения (и второго по величине значения) в столбце?
Агрегации транзакций между двумя временными метками по идентификатору в SQL
Различное количество (*) из одной и той же таблицы при запросе разными пользователями
Athena — добавить строку с 0 для всех столбцов, если значение отсутствует
REGEXP_SUBSTR в Snowflake, регулярное выражение, которое будет извлекать строку после точки (которая встречается от 0 до 2 раз)
Подзапрос: ошибка SQL [156] [S0001]: неправильный синтаксис рядом с ключевым словом «ГДЕ»
Как неявное внутреннее соединение работает с несколькими условиями предложения WHERE