【问题标题】:How can I implement a boolean tag search in SQL?如何在 SQL 中实现布尔标记搜索?
【发布时间】:2010-10-10 19:28:58
【问题描述】:

给定一个项目表,一个标签表和它们之间的连接表,什么是实现表单查询的好方法:

p1 AND p2 AND ... AND pn AND NOT n1 AND NOT n2 ... AND NOT nk

我正在使用 SQL。因此,要找到与所有标签 p1...pn 匹配且不匹配 n1...nk 的所有项目?

有没有一个好的“标准”解决方案?

【问题讨论】:

    标签: sql database search tags


    【解决方案1】:

    不知道你的架构很难说,但这样的事情会起作用:

    select article_id from articles
    inner join tag t1 on t1.article_id=articles.article_id and t1.tag='included_tag'
    inner join tag t2 on t2.article_id=articles.article_id and t2.tag='another_included_tag'
    left outer join tag t3 on t3.article_id=articles.article_id and t3.tag='dont_include_tag'
    left outer join tag t4 on t4.article_id=articles.article_id and t4.tag='also_dont_include_tag'
    where t3.tag_id is null and t4.tag_id is null
    

    对要包含的标签进行内连接,对不包含的标签进行反连接(外连接+其中必填列为空)

    【讨论】:

    • 这个实现是否比 vartec 描述的两个 IN / NOT IN 运算符组合更快? stackoverflow.com/questions/602849/…
    • 如果一篇文章可以有多个标签,vartec 的解决方案甚至都行不通
    【解决方案2】:

    我想这就是你要找的东西:

    SELECT * FROM TABLE_NAME WHERE COLUMN1 IN ('value1','value2','value3') AND COLUMN1 NOT IN ('value4','value5','value6')
    

    如果没有,请告诉我。我可能误解了你的问题。

    【讨论】:

      【解决方案3】:

      这取决于您在数据库中存储标签的方式,但您可能需要IN 运算符:

      SELECT tag FROM myTags WHERE tag IN ('p1','p2',...)
      SELECT tag FROM myTags WHERE tag NOT IN ('p1','p2',...)
      

      【讨论】:

        【解决方案4】:
        SELECT DISTINCT itemID FROM ItemsTags it, Tags t 
        WHERE it.tagID = t.ID AND t.tag IN ('p1','p2','p3') AND t.tag NOT IN ('p4','p5','p6')
        

        【讨论】:

          【解决方案5】:
          SELECT i.title
            FROM items i
           WHERE EXISTS(SELECT * FROM join_table j JOIN tags t ON t.id = j.tag_id WHERE j.item_id = i.id AND t.name = 'tag1')
             AND NOT EXISTS(SELECT * FROM join_table j JOIN tags t ON t.id = j.tag_id WHERE j.item_id = i.id AND t.name = 'tag2')
          

          SQL 服务器在这个结构方面做得很好,但 Oracle 可能需要一些提示才能让它正确(至少 5 年前它做到了)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-03-30
            • 2014-06-28
            • 2012-02-26
            • 2018-02-03
            • 1970-01-01
            • 1970-01-01
            • 2012-05-06
            • 1970-01-01
            相关资源
            最近更新 更多