如何确定字符串'word1; word2; word3; world'的元素'word4'是否在字符串'word 4','word 5','word 6','word 7'中?

时间:2013-10-28 10:32:43

标签: mysql string parsing in-clause

在我的网站上,我有一个系统可以在MySQL字符串T.Categories中对内容进行分类,如

category1;category2;category3;category4

(可能或多或少)。

另一方面,我让我的用户选择他们感兴趣的类别。基本上,他们在表单上做出选择,结果列在PHP变量$var中,看起来像

category2','category4','category5

(等)

通过请求

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

我能够确定内容是否符合他们的兴趣,只有当内容被分类为ONE SINGLE类别时才会。

以示例:

  • 我在“Cat'
  • 类别中有一张照片
  • 我的用户希望查看属于“Cat”和“Dogs”类别的照片
  • 我的SQL请求看起来像SELECT * FROM T Where T.Categories IN ('".$var."'))";

实际上,我告诉SGBD观察T.Categories的内容是否在列表$ var

当T.Categories中只有一个类别时,它正在工作。 “Cat是否$ var?是的,Cat进入'Cat','Dog'。然后我将内容提供给用户(因为Cat是$ var)”

但如果T.Categories中有多个类别,它就不再起作用了。因为整个类别存储在category1; category2; category3; category4的表单下。不幸的是: 字符串'Cat; Horse; Duck'不是'Cat','Dog'(MySQL正在寻找整个字符串)

我需要的是解析Cat; Horse; Duck三部分,以便让SGBD在$ var列表中查找每个部分。 Cat IN $ var?是的,猫进了'猫','狗'。 马在$ var?不,马不是'猫','狗'。 鸭子在$ var?不,鸭子不是'猫','狗'。 然后我将内容提供给用户(因为Cat在$ var中)。

如何使用单个请求达到目标?

2 个答案:

答案 0 :(得分:0)

实际上,您应该为每个用户存储行的类别,而不是这样做,这将使您的查询变得简单,并且也会更加规范化。但是,这将意味着更改表结构。

如果你不能这样做,你能否像这样生成你的选择请求:

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

如果您使用前导和尾随分号存储T.Categories,则无需使用concat。这意味着扫描表T,即无法使用索引。

答案 1 :(得分:0)

您的设计存在问题。您不应该在MySQL中的字符串中存储类别。

您应该将类​​别存储在新表中,并使用many-to-many表连接两者:

Article linked to Categories using a many-to-many table

一旦您有一个多对多表格将您的文章链接到您的类别,您就可以根据类别检索文章,并评估匹配所需关键字的程度。

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

您可以看到example in SQLFiddle

您还可以在此处获取更多信息:

另一种方法是使用MySQL中的全文搜索功能。更多信息: