mysql 查找用所有指定标记标记的内容的Sql查询

lrl1mhuk  于 2022-11-21  发布在  Mysql
关注(0)|答案(2)|浏览(139)

假设我有以下表:
标签
id:整数
名称:字符串

帖子

id:整数
正文:文本

标记

id:整数
tag_id:整数
post_id:整数
我将如何去写一个查询,选择所有的帖子都标记了以下标签(标签表的名称属性):“奶酪”,“葡萄酒”,“巴黎”,“弗雷斯”,“城市”,“风景”,“艺术”
另请参阅:Sql query to find things with most specified tags(注:相似,但不重复!)

qv7cva1a

qv7cva1a1#

使用IN:

SELECT p.*
  FROM POSTS p
 WHERE p.id IN (SELECT tg.post_id
                  FROM TAGGINGS tg
                  JOIN TAGS t ON t.id = tg.tag_id
                 WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
              GROUP BY tg.post_id
                HAVING COUNT(DISTINCT t.name) = 7)

使用联接

SELECT p.*
  FROM POSTS p
  JOIN (SELECT tg.post_id
          FROM TAGGINGS tg
          JOIN TAGS t ON t.id = tg.tag_id
         WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
      GROUP BY tg.post_id
        HAVING COUNT(DISTINCT t.name) = 7) x ON x.post_id = p.id

使用EXISTS

SELECT p.*
  FROM POSTS p
 WHERE EXISTS (SELECT NULL
                 FROM TAGGINGS tg
                 JOIN TAGS t ON t.id = tg.tag_id
                WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
                  AND tg.post_id = p.id
             GROUP BY tg.post_id
               HAVING COUNT(DISTINCT t.name) = 7)

说明

问题的关键是COUNT(DISTINCT t.name)需要匹配标签名称的数量,以确保所有标签都与帖子相关。如果没有DISTINCT,则存在一个风险,即重复的标签名称可能返回计数7--因此您将得到误报。

性能

大多数方法会告诉您JOIN是最优的,但是JOIN也有在结果集中重复行的风险。EXISTS将是我的下一个选择--没有重复的风险,并且通常执行更快,但是检查解释计划最终会告诉您基于您的设置和数据什么是最好的。

p8ekf7hl

p8ekf7hl2#

试试看:

Select * From Posts p
   Where Not Exists
       (Select * From tags t
        Where name in 
           ('Cheese', 'Wine', 'Paris', 
             'Frace', 'City', 'Scenic', 'Art')
           And Not Exists
             (Select * From taggings
              Where tag_id = t.Tag_Id
                And post_Id = p.Post_Id))

说明:请求一个列表的那些帖子已经 * 每一个 * 指定的一组标签与它相关联是***等价***请求那些帖子在 * 没有 * 标签在同一个指定的组,已经*没有与它相关联.即,上面的sql.

相关问题