1

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

category1;category2;category3;category4

(可能或多或少)。

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

category2','category4','category5

(ETC。)

通过请求

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

只有当内容归类为一个单一类别时,我才能确定内容是否符合他们的兴趣。

举例:

  • 我有一张照片属于“猫”类别
  • 我的用户想要查看属于“猫”和“狗”类别的照片
  • 我的 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 中吗?不,马不喜欢“猫”、“狗”。Duck 在 $var 中吗?不,鸭子不喜欢“猫”、“狗”。然后我将内容提供给用户(因为 Cat 在 $var 中)。

我怎样才能达到我的目标,使用一个单一的请求?

4

2 回答 2

0

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

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

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

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

于 2013-10-28T11:26:08.977 回答
0

你的设计有问题。您不应该将类别存储在 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 中的全文搜索功能。更多信息在这里:

于 2013-10-28T12:26:50.007 回答