代码之家  ›  专栏  ›  技术社区  ›  user2927566

如何确定字符串“word1;单词2;单词3;单词4在字符串“word4”、“word5”、“word6”、“ord7”中?

  •  1
  • user2927566  · 技术社区  · 11 年前

    在我的网站上,我有一个系统来对表格上的内容进行分类 T.Categories 在MySQL字符串中,看起来像

    category1;category2;category3;category4
    

    (可能或多或少)。

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

    category2','category4','category5
    

    (等等)

    通过请求

    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在$val中)”

    但如果T.categories中有多个类别,它就不再有效了。因为整个类别都存储在形式category1下;类别2;类别3;类别4.不幸的是: 字符串‘Cat;马Duck'不是'Cat','Dog'(MySQL正在查找整个字符串)

    我需要的是解析Cat;马分成三部分,以便SGBD在$var列表中查找每个部分。 Cat是否为$var?是的,Cat喜欢“Cat”,“Dog”。 马在$var中吗?不,马不喜欢“猫”,“狗”。 Duck在$var中吗?不,鸭子不喜欢“猫”,“狗”。 然后我把内容发给用户(因为Cat在$var中)。

    我怎样才能通过一个请求达到我的目标?

    2 回复  |  直到 11 年前
        1
  •  0
  •   Community CDub    8 年前

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

        2
  •  0
  •   muhmud    11 年前

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

    如果你不能做到这一点,你可以这样生成选择请求吗:

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

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