针对多对多关系优化查询以搜索不相关的标记

时间:2012-12-18 04:42:41

标签: mysql many-to-many

我正在开发一个应用程序,它将通过在搜索池中禁用不相关的标记来执行某种智能数据搜索。

例如(抱歉,如果我的格式可能很糟糕),给定此表:

    _id  |  _tagname
    1       A
    1       B
    1       C
    2       A
    2       B
    3       A
    4       B
    5       C
    6       D

当用户选择标记 A 时,(每个标记选择将执行以下操作):

  1. 获取与标记匹配的ID - > 1,2,3 现在将成为新的搜索池
  2. 隐藏所有不相关的标签 - > D ,因为代码 B C 将允许用户过滤代码以获取ID 1
  3. TL; DR :这是我目前的方法,我想知道是否有办法优化它,因为目前花费的时间太长才能得到结果

    SELECT _tagname FROM datatags WHERE 
    (_tagname) NOT IN 
    ( SELECT _tagname FROM datatags WHERE 
    _id IN (1,2,3)) 
    GROUP BY _tagname
    

    谢谢!这是我第一次发帖提问,请放轻松一下:)

    编辑:格式化

1 个答案:

答案 0 :(得分:0)

您最终是在寻找一起出现的标签,还是您真的想要出现奇数标签?

以下是查找相关标记的两种方法(为{ A, B, C }AB返回C,并为{ D }返回D })

  • 使用相关子查询:

    SELECT DISTINCT _tagname 
    FROM   datatags 
    WHERE  _id IN (SELECT _id 
                   FROM   datatags 
                   WHERE  _tagname = ?)
    
  • 使用自我加入:

    SELECT DISTINCT b._tagname 
    FROM   datatags a 
           JOIN datatags b USING (_id) 
    WHERE  a._tagname = 'A' 
    

对于反向(从不与给定标记一起出现的标记),您会发现整个标记集与相关标记之间的差异。 MySQL不支持MINUS,但这里有一种查找无关标签的方法:

  • 将相关子查询与自联接一起使用:

    SELECT _tagname 
    FROM   datatags 
           LEFT JOIN (SELECT DISTINCT _tagname 
                      FROM   datatags 
                      WHERE  _id IN (SELECT _id 
                                     FROM   datatags 
                                     WHERE  _tagname = ?)) a USING (_tagname) 
    WHERE  a._tagname IS NULL