Как определить, находится ли элемент "word4" в строке "word1;word2;word3;word4" в строке "word4", "word5", "word6", "word7"?

На моем сайте у меня есть система для классификации содержимого таблицы T.Categories в строке MySQL выглядит как

category1;category2;category3;category4

(это может быть более или менее).

С другой стороны, я позволю своим пользователям выбирать интересующие их категории. По сути, они делают свой выбор в форме, а результат указывается в переменной PHP. $var выглядит как

category2','category4','category5

(так далее.)

По запросу

T.Categories IN ('".$var."'))";

Я могу определить, соответствует ли контент их интересам, ТОЛЬКО КОГДА контент классифицируется в ОДНОЙ ОДНОЙ.

К примеру:

  • У меня есть фото в категории под названием "Кошка"
  • Мои пользователи хотят видеть фотографии, которые принадлежат категориям 'Cat' и 'Dogs'
  • Мой запрос SQL выглядит SELECT * FROM T Where T.Categories IN ('".$var."'))";

Практически, я говорю SGBD, чтобы посмотреть, находится ли содержимое T.Categories в списке $var

Это работает, когда в T.Categories есть только одна категория. "Является ли Cat IN $var? Да, Cat находится в" Cat "," Dog ". Затем я получаю контент для пользователя (потому что Cat находится в $var)"

Но это больше не работает, если в T.Categories есть более одной категории. Потому что целые категории хранятся под формой категория1; категория2; категория3; категория4. К сожалению, строка "Cat;Horse;Duck" не входит в "Cat", "Dog" (MySQL ищет всю строку)

Мне нужно разобрать Cat;Horse;Duck в трех частях, чтобы SGBD искал каждую часть в списке $var. Cat IN $var? да, кошка в "кошка", "собака". Лошадь в $var? нет, Лошадь не в "Кошку", "Собаку". Утка в $var? нет, утка не в "кошка", "собака". Затем я передаю контент пользователю (потому что Cat находится в $var).

Как я мог достичь своей цели, используя один запрос?

2 ответа

Решение

Есть проблема с вашим дизайном. Вы не должны хранить категории в строке в MySQL.

Категории следует хранить в новой таблице, в которой таблица " многие ко многим" связывает две таблицы:

Статья связана с категориями с использованием таблицы

Если у вас есть таблица "многие ко многим", связывающая ваши Статьи с вашими категориями, вы можете извлечь статьи, основанные на категориях, и оценить, насколько хорошо соответствуют необходимые ключевые слова.

SELECT A.*, L.Relevance
FROM Article AS A
INNER JOIN
(
    SELECT AC.ArticleID, COUNT(AC.CategoryID) AS Relevance
    FROM ArticleCategory AS AC
    INNER JOIN Category AS C
    ON AC.CategoryID = C.CategoryID   
    WHERE C.Name IN ('Cat','Dog','Donkey','Chicken')
    GROUP BY AC.ArticleID
) AS L
ON A.ArticleID = L.ArticleID
ORDER BY L.Relevance DESC, Name

Вы можете увидеть пример в SQLFiddle.

Вы также можете получить больше информации здесь:

Альтернативой является использование функций полнотекстового поиска в MySQL. Больше информации здесь:

Действительно, вы должны хранить категории в строках для каждого пользователя, а не делать это, что сделает ваш запрос простым и будет более нормализованным. Однако это будет означать изменения в ваших структурах таблиц.

Если вы не можете этого сделать, вы можете сгенерировать ваш запрос на выборку следующим образом:

SELECT * FROM T Where concat(';', T.Categories, ';') like '%;cat;%' or
                      concat(';', T.Categories, ';') like '%;dog;%'

Если вы сохранили T.Categories с ведущими и конечными точками с запятой вам не нужно использовать concat, Это будет означать сканирование таблицы T, то есть индексы не могут быть использованы.

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