Сопоставить два столбца списка ключевых слов с другим столбцом для совпадений - PullRequest
1 голос
/ 12 августа 2010

Я использую .NET 4.0 & C # и SQL Server 2008. У меня есть таблица Products со столбцом под названием Keywords . У меня есть еще одна таблица интересов с 2 столбцами Принять и Отклонить . Все 3 столбца содержат ключевые слова, разделенные запятыми. Мне нужно соответствовать:

  1. Если значения Accept & Reject пусты, значит, есть совпадение
  2. Если в Accept есть ключевые слова, то между Accept & Keywords должно быть хотя бы одно совпадение ключевых слов
  3. Если в «Отклонить» есть ключевые слова, между «Отклонить и ключевыми словами» не должно быть совпадений
  4. Сочетание 2 и 3

В идеале я хотел бы сделать это в запросе SQL. Я открыт для хранимых процедур Managed или T-SQL в этом порядке.


ОК, основываясь на комментариях, я добавил эти таблицы:

Ключевые слова_Продукты [id (FK to Products), Ключевое слово]
Keywords_Accepted [id (FK to User), Keyword]
Keywords_Rejected [id (от FK до пользователя), ключевое слово]

Итак, мне нужен набор продуктов для данного идентификатора пользователя, основанный на 4 правилах выше.

Ответы [ 4 ]

2 голосов
/ 12 августа 2010

Я бы предложил вам реструктурировать вашу БД, как следует из ограниченной информации, которой я обладаю:

Product
---------
ProductId - int
ProductName - varchar
Accepted - bit

ProductKeywords
---------------
KeywordId - int
ProductId - int
Keyword - varchar

Я немного смущен структурой ваших данных. Будет ли эта модель работать для вас? Если это так, это предотвратит много проблем с обслуживаемостью и производительностью в будущем.

2 голосов
/ 12 августа 2010

Настоящая проблема в том, что списки ключевых слов находятся в одном поле.Разбиение списка через запятую на самом деле не то, для чего SQL был предназначен.

На самом деле они должны быть в таблицах 1-ко-многим (ProductKeywords, AcceptInterest, RejectInterests).

1 голос
/ 13 августа 2010

Один параметр для строк, разделенных запятыми:

  • Функции табличных значений (функция, принимающая строку с разделителями-запятыми в качестве входных данных и возвращающая таблицу)

Соедините результаты вашей табличной функции «Принять» с результатами вашей табличной функции «Ключевые слова», и если строки возвращены, вы знаете, что у вас есть совпадение.

Второй вариант - создать функцию, которая вытягивает Word n ​​из одного поля, а затем выполняет CHARINDEX () и т. Д. Для второго поля. Поместите это в цикл WHILE, и как только вы получите возврат CHARINDEX () больше нуля, выйдите из цикла.

0 голосов
/ 13 августа 2010

Если вы застряли со структурой таблицы как есть (и я подозреваю, что вы есть), то вам, вероятно, лучше разбить ее на несколько частей. Ваша первая задача - создать функцию, которая может разбивать строки на основе разделителя. Как это сделать, ответили на другой вопрос .

Также было бы полезно, если бы вы создали уточнение для функции разделения, создав одну особенность для поля Ключевые слова в таблице Продукты. Кое-что, где вы можете передать ProductId и заставить его вернуть ключевые слова для этого ProductId.

Оттуда вы можете выбрать интересы, соответствующие данному продукту, например,

SELECT * FROM Interests i
WHERE 
    (i.Accept = '' AND i.Reject = '')
    OR
    (
        EXISTS (SELECT * FROM Split(',', i.Accept) ia WHERE ia.[Value] IN (ProductKeywords(@ProductId)))
        AND
        NOT EXISTS (SELECT * FROM Split(',', i.Reject) ir WHERE ir.[Value] IN (ProductKeywords(@ProductId)))
    )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...